diff --git a/README.md b/README.md index 7bc7b74..9363fe2 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,12 @@ fn main() { let info = PlatformInfo::new().unwrap(); // println!("info={:#?}", info); - println!("{}", (info.sysname()).unwrap_or_else(|os_s| os_s.to_string_lossy())); - println!("{}", (info.nodename()).unwrap_or_else(|os_s| os_s.to_string_lossy())); - println!("{}", (info.release()).unwrap_or_else(|os_s| os_s.to_string_lossy())); - println!("{}", (info.version()).unwrap_or_else(|os_s| os_s.to_string_lossy())); - println!("{}", (info.machine()).unwrap_or_else(|os_s| os_s.to_string_lossy())); - println!("{}", (info.osname()).unwrap_or_else(|os_s| os_s.to_string_lossy())); + println!("{}", info.sysname().to_string_lossy()); + println!("{}", info.nodename().to_string_lossy()); + println!("{}", info.release().to_string_lossy()); + println!("{}", info.version().to_string_lossy()); + println!("{}", info.machine().to_string_lossy()); + println!("{}", info.osname().to_string_lossy()); } ``` diff --git a/examples/ex.rs b/examples/ex.rs index f7f0024..71434db 100644 --- a/examples/ex.rs +++ b/examples/ex.rs @@ -9,28 +9,10 @@ fn main() { let info = PlatformInfo::new().unwrap(); // println!("info={:#?}", info); - println!( - "{}", - (info.sysname()).unwrap_or_else(|os_s| os_s.to_string_lossy()) - ); - println!( - "{}", - (info.nodename()).unwrap_or_else(|os_s| os_s.to_string_lossy()) - ); - println!( - "{}", - (info.release()).unwrap_or_else(|os_s| os_s.to_string_lossy()) - ); - println!( - "{}", - (info.version()).unwrap_or_else(|os_s| os_s.to_string_lossy()) - ); - println!( - "{}", - (info.machine()).unwrap_or_else(|os_s| os_s.to_string_lossy()) - ); - println!( - "{}", - (info.osname()).unwrap_or_else(|os_s| os_s.to_string_lossy()) - ); + println!("{}", info.sysname().to_string_lossy()); + println!("{}", info.nodename().to_string_lossy()); + println!("{}", info.release().to_string_lossy()); + println!("{}", info.version().to_string_lossy()); + println!("{}", info.machine().to_string_lossy()); + println!("{}", info.osname().to_string_lossy()); } diff --git a/src/lib.rs b/src/lib.rs index 8595d81..914ebd7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,8 +31,7 @@ use of every feature. #![warn(unused_results)] -use std::borrow::Cow; -use std::ffi::OsString; +use std::ffi::OsStr; mod lib_impl; pub use lib_impl::*; @@ -41,20 +40,20 @@ pub use lib_impl::*; // ref: @@ pub trait PlatformInfoAPI { /// The name of this implementation of the operating system. - fn sysname(&self) -> Result, &OsString>; + fn sysname(&self) -> &OsStr; /// The node name (network node hostname) of this machine. - fn nodename(&self) -> Result, &OsString>; + fn nodename(&self) -> &OsStr; /// The current release level of the operating system. - fn release(&self) -> Result, &OsString>; + fn release(&self) -> &OsStr; /// The current version level of the current release. - fn version(&self) -> Result, &OsString>; + fn version(&self) -> &OsStr; /// The name of the current system's hardware. - fn machine(&self) -> Result, &OsString>; + fn machine(&self) -> &OsStr; /// The name of the current OS. - fn osname(&self) -> Result, &OsString>; + fn osname(&self) -> &OsStr; } diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 627bba4..5be1fd1 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -19,9 +19,8 @@ #![warn(unused_results)] -use std::borrow::Cow; use std::error::Error; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fmt; use std::fmt::{Debug, Formatter}; @@ -62,46 +61,28 @@ impl PlatformInfo { } impl PlatformInfoAPI for PlatformInfo { - fn sysname(&self) -> Result, &OsString> { - match self.sysname.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.sysname), - } + fn sysname(&self) -> &OsStr { + &self.sysname } - fn nodename(&self) -> Result, &OsString> { - match self.nodename.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.nodename), - } + fn nodename(&self) -> &OsStr { + &self.nodename } - fn release(&self) -> Result, &OsString> { - match self.release.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.release), - } + fn release(&self) -> &OsStr { + &self.release } - fn version(&self) -> Result, &OsString> { - match self.version.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.version), - } + fn version(&self) -> &OsStr { + &self.version } - fn machine(&self) -> Result, &OsString> { - match self.machine.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.machine), - } + fn machine(&self) -> &OsStr { + &self.machine } - fn osname(&self) -> Result, &OsString> { - match self.osname.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.osname), - } + fn osname(&self) -> &OsStr { + &self.osname } } @@ -213,15 +194,15 @@ mod unix_safe { #[test] fn test_osname() { let info = PlatformInfo::new().unwrap(); - let osname = match info.osname() { - Ok(str) => { - println!("osname = [{}]'{:?}'", str.len(), str); - str + let osname = match info.osname().to_os_string().into_string() { + Ok(s) => { + println!("osname = [{}]'{}'", s.len(), s); + s } Err(os_s) => { let s = os_s.to_string_lossy(); println!("osname = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); - Cow::from(String::from(s)) + String::from(s) } }; assert!(osname.starts_with(crate::HOST_OS_NAME)); diff --git a/src/platform/unknown.rs b/src/platform/unknown.rs index 77d1ac2..e7b878b 100644 --- a/src/platform/unknown.rs +++ b/src/platform/unknown.rs @@ -11,46 +11,49 @@ #![warn(unused_results)] -use std::borrow::Cow; use std::error::Error; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use crate::PlatformInfoAPI; // PlatformInfo /// Handles initial retrieval and holds information for the current platform ("unknown" in this case). #[derive(Clone, Debug, PartialEq, Eq)] -pub struct PlatformInfo(()); +pub struct PlatformInfo { + unknown: OsString, +} impl PlatformInfo { pub fn new() -> Result> { - Ok(Self(())) + Ok(Self { + unknown: OsString::from("unknown"), + }) } } impl PlatformInfoAPI for PlatformInfo { - fn sysname(&self) -> Result, &OsString> { - Ok(Cow::from("unknown")) + fn sysname(&self) -> &OsStr { + &self.unknown } - fn nodename(&self) -> Result, &OsString> { - Ok(Cow::from("unknown")) + fn nodename(&self) -> &OsStr { + &self.unknown } - fn release(&self) -> Result, &OsString> { - Ok(Cow::from("unknown")) + fn release(&self) -> &OsStr { + &self.unknown } - fn version(&self) -> Result, &OsString> { - Ok(Cow::from("unknown")) + fn version(&self) -> &OsStr { + &self.unknown } - fn machine(&self) -> Result, &OsString> { - Ok(Cow::from("unknown")) + fn machine(&self) -> &OsStr { + &self.unknown } - fn osname(&self) -> Result, &OsString> { - Ok(Cow::from("unknown")) + fn osname(&self) -> &OsStr { + &self.unknown } } @@ -58,10 +61,10 @@ impl PlatformInfoAPI for PlatformInfo { fn test_unknown() { let platform_info = PlatformInfo::new().unwrap(); - assert_eq!(platform_info.sysname().unwrap(), "unknown"); - assert_eq!(platform_info.nodename().unwrap(), "unknown"); - assert_eq!(platform_info.release().unwrap(), "unknown"); - assert_eq!(platform_info.version().unwrap(), "unknown"); - assert_eq!(platform_info.machine().unwrap(), "unknown"); - assert_eq!(platform_info.osname().unwrap(), "unknown"); + assert_eq!(platform_info.sysname().to_string_lossy(), "unknown"); + assert_eq!(platform_info.nodename().to_string_lossy(), "unknown"); + assert_eq!(platform_info.release().to_string_lossy(), "unknown"); + assert_eq!(platform_info.version().to_string_lossy(), "unknown"); + assert_eq!(platform_info.machine().to_string_lossy(), "unknown"); + assert_eq!(platform_info.osname().to_string_lossy(), "unknown"); } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 3c5ff99..c85cc50 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -30,10 +30,9 @@ #![warn(unused_results)] -use std::borrow::Cow; use std::convert::TryFrom; use std::error::Error; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fmt; use std::fmt::{Debug, Formatter}; use std::io; @@ -61,6 +60,11 @@ pub struct PlatformInfo { pub system_info: WinApiSystemInfo, pub version_info: WinOsVersionInfo, // * private-use fields + sysname: OsString, + nodename: OsString, + release: OsString, + version: OsString, + machine: OsString, osname: OsString, } @@ -72,52 +76,51 @@ impl PlatformInfo { let system_info = WinApiSystemInfo(WinAPI_GetNativeSystemInfo()); let version_info = os_version_info()?; + let sysname = determine_sysname(); + let nodename = computer_name.clone(); + let release = version_info.release.clone(); + let version = version_info.version.clone(); + let machine = determine_machine(&system_info); let osname = determine_osname(&version_info); Ok(Self { computer_name, system_info, version_info, + /* private use */ + sysname, + nodename, + release, + version, + machine, osname, }) } } impl PlatformInfoAPI for PlatformInfo { - fn sysname(&self) -> Result, &OsString> { - Ok(Cow::from(determine_sysname())) + fn sysname(&self) -> &OsStr { + &self.sysname } - fn nodename(&self) -> Result, &OsString> { - match self.computer_name.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.computer_name), - } + fn nodename(&self) -> &OsStr { + &self.nodename } - fn release(&self) -> Result, &OsString> { - match self.version_info.release.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.version_info.release), - } + fn release(&self) -> &OsStr { + &self.release } - fn version(&self) -> Result, &OsString> { - match self.version_info.version.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.version_info.version), - } + fn version(&self) -> &OsStr { + &self.version } - fn machine(&self) -> Result, &OsString> { - Ok(Cow::from(determine_machine(&self.system_info))) + fn machine(&self) -> &OsStr { + &self.machine } - fn osname(&self) -> Result, &OsString> { - match self.osname.to_str() { - Some(str) => Ok(Cow::from(str)), - None => Err(&self.osname), - } + fn osname(&self) -> &OsStr { + &self.osname } } @@ -476,7 +479,7 @@ fn winos_name( //=== -fn determine_machine(system_info: &WinApiSystemInfo) -> String { +fn determine_machine(system_info: &WinApiSystemInfo) -> OsString { let arch = system_info.wProcessorArchitecture(); // ref: [SYSTEM_INFO structure](https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info) @@ @@ -501,7 +504,7 @@ fn determine_machine(system_info: &WinApiSystemInfo) -> String { _ => "unknown", }; - String::from(arch_str) + OsString::from(arch_str) } fn determine_osname(version_info: &WinOsVersionInfo) -> OsString { @@ -514,10 +517,10 @@ fn determine_osname(version_info: &WinOsVersionInfo) -> OsString { osname } -fn determine_sysname() -> String { +fn determine_sysname() -> OsString { // As of 2023-02, possible Windows kernels == [ "Windows_9x", "Windows_NT" ] // * "Windows_9x" hit end-of-service-life on 2006-07-11 (ref: [Windows_9x](https://en.wikipedia.org/wiki/Windows_9x) @@ ) - String::from("Windows_NT") // compatible with `busybox` and MS (from std::env::var("OS")) + OsString::from("Windows_NT") // compatible with `busybox` and MS (from std::env::var("OS")) } //=== Tests @@ -525,19 +528,8 @@ fn determine_sysname() -> String { #[test] fn test_sysname() { let info = PlatformInfo::new().unwrap(); - let sysname = match info.sysname() { - Ok(str) => { - println!("sysname = [{}]'{:?}'", str.len(), str); - str - } - Err(os_s) => { - let s = os_s.to_string_lossy(); - println!("sysname = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); - Cow::from(String::from(s)) - } - }; - - let expected = std::env::var("OS").unwrap_or_else(|_| String::from("Windows_NT")); + let sysname = info.sysname().to_os_string(); + let expected = std::env::var_os("OS").unwrap_or_else(|| OsString::from("Windows_NT")); assert_eq!(sysname, expected); } @@ -545,15 +537,15 @@ fn test_sysname() { #[allow(non_snake_case)] fn test_nodename_no_trailing_NUL() { let info = PlatformInfo::new().unwrap(); - let nodename = match info.nodename() { - Ok(str) => { - println!("nodename = [{}]'{:?}'", str.len(), str); - str + let nodename = match info.nodename().to_os_string().into_string() { + Ok(s) => { + println!("nodename = [{}]'{}'", s.len(), s); + s } Err(os_s) => { let s = os_s.to_string_lossy(); println!("nodename = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); - Cow::from(String::from(s)) + String::from(s) } }; let trimmed = nodename.trim().trim_end_matches(|c| c == '\0'); @@ -588,15 +580,15 @@ fn test_machine() { println!("target={:#?}", target); let info = PlatformInfo::new().unwrap(); - let machine = match info.machine() { - Ok(str) => { - println!("machine = [{}]'{:?}'", str.len(), str); - str + let machine = match info.machine().to_os_string().into_string() { + Ok(s) => { + println!("machine = [{}]'{:?}'", s.len(), s); + s } Err(os_s) => { let s = os_s.to_string_lossy(); - println!("machine = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); - Cow::from(String::from(s)) + println!("machine = [{}]'{:?}' => '{:?}'", os_s.len(), os_s, s); + String::from(s) } }; @@ -606,15 +598,15 @@ fn test_machine() { #[test] fn test_osname() { let info = PlatformInfo::new().unwrap(); - let osname = match info.osname() { - Ok(str) => { - println!("osname = [{}]'{:?}'", str.len(), str); - str + let osname = match info.osname().to_os_string().into_string() { + Ok(s) => { + println!("osname = [{}]'{:?}'", s.len(), s); + s } Err(os_s) => { let s = os_s.to_string_lossy(); - println!("osname = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); - Cow::from(String::from(s)) + println!("osname = [{}]'{:?}' => '{:?}'", os_s.len(), os_s, s); + String::from(s) } }; assert!(osname.starts_with(crate::HOST_OS_NAME)); diff --git a/tests/integration_test.rs b/tests/integration_test.rs index b269248..2cdd43d 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -11,19 +11,72 @@ fn platform() -> Result<(), String> { Err(error) => panic!("{}", error), }; - let sysname = (uname.sysname()).unwrap_or_else(|os_s| os_s.to_string_lossy()); - let nodename = (uname.nodename()).unwrap_or_else(|os_s| os_s.to_string_lossy()); - let release = (uname.release()).unwrap_or_else(|os_s| os_s.to_string_lossy()); - let version = (uname.version()).unwrap_or_else(|os_s| os_s.to_string_lossy()); - let machine = (uname.machine()).unwrap_or_else(|os_s| os_s.to_string_lossy()); - let osname = (uname.osname()).unwrap_or_else(|os_s| os_s.to_string_lossy()); - - println!("sysname = [{}]'{}'", sysname.len(), sysname); - println!("nodename = [{}]'{}'", nodename.len(), nodename); - println!("release = [{}]'{}'", release.len(), release); - println!("version = [{}]'{}'", version.len(), version); - println!("machine = [{}]'{}'", machine.len(), machine); - println!("osname = [{}]'{}'", osname.len(), osname); + let sysname = match uname.sysname().to_os_string().into_string() { + Ok(s) => { + println!("sysname = [{}]'{}'", s.len(), s); + s + } + Err(os_s) => { + let s = os_s.to_string_lossy(); + println!("sysname = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); + String::from(s) + } + }; + let nodename = match uname.nodename().to_os_string().into_string() { + Ok(s) => { + println!("nodename = [{}]'{}'", s.len(), s); + s + } + Err(os_s) => { + let s = os_s.to_string_lossy(); + println!("nodename = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); + String::from(s) + } + }; + let release = match uname.release().to_os_string().into_string() { + Ok(s) => { + println!("release = [{}]'{}'", s.len(), s); + s + } + Err(os_s) => { + let s = os_s.to_string_lossy(); + println!("release = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); + String::from(s) + } + }; + let version = match uname.version().to_os_string().into_string() { + Ok(s) => { + println!("version = [{}]'{}'", s.len(), s); + s + } + Err(os_s) => { + let s = os_s.to_string_lossy(); + println!("version = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); + String::from(s) + } + }; + let machine = match uname.machine().to_os_string().into_string() { + Ok(s) => { + println!("machine = [{}]'{}'", s.len(), s); + s + } + Err(os_s) => { + let s = os_s.to_string_lossy(); + println!("machine = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); + String::from(s) + } + }; + let osname = match uname.osname().to_os_string().into_string() { + Ok(s) => { + println!("osname = [{}]'{}'", s.len(), s); + s + } + Err(os_s) => { + let s = os_s.to_string_lossy(); + println!("osname = [{}]'{:?}' => '{}'", os_s.len(), os_s, s); + String::from(s) + } + }; assert!(!sysname.is_empty()); assert!(!nodename.is_empty()); @@ -43,12 +96,12 @@ fn platform_no_invisible_contents() -> Result<(), String> { Err(error) => panic!("{}", error), }; - let sysname = (uname.sysname()).unwrap_or_else(|os_str| os_str.to_string_lossy()); - let nodename = (uname.nodename()).unwrap_or_else(|os_str| os_str.to_string_lossy()); - let release = (uname.release()).unwrap_or_else(|os_str| os_str.to_string_lossy()); - let version = (uname.version()).unwrap_or_else(|os_str| os_str.to_string_lossy()); - let machine = (uname.machine()).unwrap_or_else(|os_str| os_str.to_string_lossy()); - let osname = (uname.osname()).unwrap_or_else(|os_str| os_str.to_string_lossy()); + let sysname = uname.sysname().to_string_lossy(); + let nodename = uname.nodename().to_string_lossy(); + let release = uname.release().to_string_lossy(); + let version = uname.version().to_string_lossy(); + let machine = uname.machine().to_string_lossy(); + let osname = uname.osname().to_string_lossy(); let s = format!("sysname='{sysname}';nodename='{nodename}';release='{release}';version='{version}';machine='{machine}';osname='{osname}'"); println!("s = [{}]\"{}\"", s.len(), s);