refactor/API ~ revise PlatformInfoAPI trait (to () -> &OsStr)

This commit is contained in:
Roy Ivy III
2023-02-12 12:48:32 -06:00
parent bae43fc47b
commit e84b6aae7d
7 changed files with 186 additions and 176 deletions
+6 -6
View File
@@ -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());
}
```
+6 -24
View File
@@ -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());
}
+7 -8
View File
@@ -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: <https://www.gnu.org/software/libc/manual/html_node/Platform-Type.html> @@ <https://archive.is/YjjWJ>
pub trait PlatformInfoAPI {
/// The name of this implementation of the operating system.
fn sysname(&self) -> Result<Cow<str>, &OsString>;
fn sysname(&self) -> &OsStr;
/// The node name (network node hostname) of this machine.
fn nodename(&self) -> Result<Cow<str>, &OsString>;
fn nodename(&self) -> &OsStr;
/// The current release level of the operating system.
fn release(&self) -> Result<Cow<str>, &OsString>;
fn release(&self) -> &OsStr;
/// The current version level of the current release.
fn version(&self) -> Result<Cow<str>, &OsString>;
fn version(&self) -> &OsStr;
/// The name of the current system's hardware.
fn machine(&self) -> Result<Cow<str>, &OsString>;
fn machine(&self) -> &OsStr;
/// The name of the current OS.
fn osname(&self) -> Result<Cow<str>, &OsString>;
fn osname(&self) -> &OsStr;
}
+18 -37
View File
@@ -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<Cow<str>, &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<Cow<str>, &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<Cow<str>, &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<Cow<str>, &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<Cow<str>, &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<Cow<str>, &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));
+25 -22
View File
@@ -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<Self, Box<dyn Error>> {
Ok(Self(()))
Ok(Self {
unknown: OsString::from("unknown"),
})
}
}
impl PlatformInfoAPI for PlatformInfo {
fn sysname(&self) -> Result<Cow<str>, &OsString> {
Ok(Cow::from("unknown"))
fn sysname(&self) -> &OsStr {
&self.unknown
}
fn nodename(&self) -> Result<Cow<str>, &OsString> {
Ok(Cow::from("unknown"))
fn nodename(&self) -> &OsStr {
&self.unknown
}
fn release(&self) -> Result<Cow<str>, &OsString> {
Ok(Cow::from("unknown"))
fn release(&self) -> &OsStr {
&self.unknown
}
fn version(&self) -> Result<Cow<str>, &OsString> {
Ok(Cow::from("unknown"))
fn version(&self) -> &OsStr {
&self.unknown
}
fn machine(&self) -> Result<Cow<str>, &OsString> {
Ok(Cow::from("unknown"))
fn machine(&self) -> &OsStr {
&self.unknown
}
fn osname(&self) -> Result<Cow<str>, &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");
}
+52 -60
View File
@@ -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<Cow<str>, &OsString> {
Ok(Cow::from(determine_sysname()))
fn sysname(&self) -> &OsStr {
&self.sysname
}
fn nodename(&self) -> Result<Cow<str>, &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<Cow<str>, &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<Cow<str>, &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<Cow<str>, &OsString> {
Ok(Cow::from(determine_machine(&self.system_info)))
fn machine(&self) -> &OsStr {
&self.machine
}
fn osname(&self) -> Result<Cow<str>, &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) @@ <https://archive.is/cqbrj>
@@ -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) @@ <https://archive.is/wip/K6fhN>)
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));
+72 -19
View File
@@ -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);