diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b41eed..3f5f16c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ available [on GitHub][2]. * [#111](https://github.com/chshersh/tool-sync/issues/111): Adds repo URLs to the output of `default-config` and `install` commands (by [@crudiedo][crudiedo]) +* [#110](https://github.com/chshersh/tool-sync/issues/110): + Adds the 'OS' enum and improves error messages + (by [@crudiedo][crudiedo]) ### Fixed diff --git a/src/config/toml.rs b/src/config/toml.rs index 807b6c2..f4a0211 100644 --- a/src/config/toml.rs +++ b/src/config/toml.rs @@ -7,6 +7,7 @@ use toml::{map::Map, Value}; use crate::config::schema::{Config, ConfigAsset}; use crate::infra::err; use crate::model::asset_name::AssetName; +use crate::model::os::OS; #[derive(Debug, PartialEq, Eq)] pub enum TomlError { @@ -99,9 +100,9 @@ fn decode_asset_name(table: &Map) -> AssetName { }, Some(table) => { - let linux = str_by_key(table, "linux"); - let macos = str_by_key(table, "macos"); - let windows = str_by_key(table, "windows"); + let linux = str_by_key(table, &OS::Linux.to_string()); + let macos = str_by_key(table, &OS::MacOS.to_string()); + let windows = str_by_key(table, &OS::Windows.to_string()); AssetName { linux, diff --git a/src/model.rs b/src/model.rs index d96f04d..ccab5fd 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,3 +1,4 @@ pub mod asset_name; +pub mod os; pub mod release; pub mod tool; diff --git a/src/model/asset_name.rs b/src/model/asset_name.rs index f939780..14c4e9e 100644 --- a/src/model/asset_name.rs +++ b/src/model/asset_name.rs @@ -1,4 +1,4 @@ -use std::env; +use crate::model::os::{get_current_os, OS}; /// Part of the name for each OS to identify proper asset #[derive(Debug, PartialEq, Eq)] @@ -9,17 +9,13 @@ pub struct AssetName { } impl AssetName { - /// Get the current OS where the 'tool-sync' is running and extract the - /// corresponding name of the downloaded tool - /// - /// !!! WARNING !!! This function uses OS of the system where 'tool-sync' was - /// compiled. The function relies on the assumption that a user will run e.g. - /// the macOS executable on macOS + /// Get the current OS and extract the corresponding name + /// of the downloaded tool pub fn get_name_by_os(&self) -> Option<&String> { - match env::consts::OS { - "windows" => self.windows.as_ref(), - "macos" => self.macos.as_ref(), - _ => self.linux.as_ref(), + match get_current_os() { + OS::Windows => self.windows.as_ref(), + OS::MacOS => self.macos.as_ref(), + OS::Linux => self.linux.as_ref(), } } } diff --git a/src/model/os.rs b/src/model/os.rs new file mode 100644 index 0000000..8a811ab --- /dev/null +++ b/src/model/os.rs @@ -0,0 +1,63 @@ +use std::env; +use std::fmt::{Display, Formatter}; + +#[derive(Debug, PartialEq, Eq)] +pub enum OS { + Windows, + MacOS, + Linux, +} + +/// Return the current OS where the 'tool-sync' is running +/// +/// !!! WARNING !!! This function uses OS of the system where 'tool-sync' was +/// compiled. The function relies on the assumption that a user will run e.g. +/// the macOS executable on macOS +pub fn get_current_os() -> OS { + match env::consts::OS { + "windows" => OS::Windows, + "macos" => OS::MacOS, + _ => OS::Linux, + } +} + +impl Display for OS { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Windows => { + write!(f, "windows") + } + Self::MacOS => { + write!(f, "macos") + } + Self::Linux => { + write!(f, "linux") + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn current_os() { + let os = get_current_os(); + + if cfg!(target_os = "windows") { + assert_eq!(os, OS::Windows); + } else if cfg!(target_os = "macos") { + assert_eq!(os, OS::MacOS); + } else { + assert_eq!(os, OS::Linux); + } + } + + #[test] + fn os_display() { + assert_eq!(OS::Windows.to_string(), String::from("windows")); + assert_eq!(OS::MacOS.to_string(), String::from("macos")); + assert_eq!(OS::Linux.to_string(), String::from("linux")); + } +} diff --git a/src/model/release.rs b/src/model/release.rs index e4e24d4..81c7eed 100644 --- a/src/model/release.rs +++ b/src/model/release.rs @@ -1,8 +1,8 @@ use serde::Deserialize; -use std::env; use std::fmt::{Display, Formatter, Write}; use crate::infra::err; +use crate::model::os::get_current_os; #[derive(Deserialize, Debug)] pub struct Release { @@ -35,8 +35,8 @@ impl Display for AssetError { Self::OsSelectorUnknown => { write!( f, - "Unknown asset selector for OS: {}. Specify 'asset_name.your_os' in the cofig.", - env::consts::OS + "Unknown asset selector for the current OS. Specify 'asset_name.{}' in the config.", + get_current_os() ) } Self::NotFound(asset_name) => {