#[cfg(target_os = "macos")]
mod mac;
#[cfg(target_os = "windows")]
mod win;
#[derive(Debug, Clone)]
pub struct SystemInfo {
pub cores: usize,
pub memory: String,
pub serial_number: Vec<String>,
pub hardware_uuid: String,
pub uuid: String,
}
impl SystemInfo {
pub fn new() -> Result<Self, String> {
let mut that = Self {
cores: 0,
memory: "".to_string(),
serial_number: vec![],
hardware_uuid: "".to_string(),
uuid: "".to_string(),
};
if cfg!(target_os = "macos") {
#[cfg(target_os = "macos")]
{
return that.mac_os();
}
}
if cfg!(target_os = "windows") {
#[cfg(target_os = "windows")]
{
return that.windows();
}
}
Ok(that)
}
#[cfg(target_os = "macos")]
pub fn mac_os(&mut self) -> Result<Self, String> {
self.uuid = mac::get_uuid().unwrap_or("".to_string());
self.serial_number = vec![self.uuid.clone()];
Ok(self.clone())
}
#[cfg(target_os = "windows")]
pub fn windows(&mut self) -> Result<&mut Self, String> {
let disk_output = match Command::new("wmic")
.args(&["diskdrive", "get", "SerialNumber"])
.output() {
Ok(e) => e,
Err(e) => {
return Err(format!("{}", e.to_string()));
}
};
let serial_number = String::from_utf8_lossy(&disk_output.stdout);
for line in serial_number.lines() {
let text = line.trim();
if !text.contains("SerialNumber") && !text.is_empty() {
self.serial_number.push(text.to_string())
}
}
let cpu_output = match Command::new("wmic")
.args(&["cpu", "get", "NumberOfCores"])
.output() {
Ok(e) => e,
Err(e) => {
return Err(format!("Failed to get CPU info: {}", e.to_string()));
}
};
let cpu_info = String::from_utf8_lossy(&cpu_output.stdout);
for line in cpu_info.lines() {
let text = line.trim();
if text.chars().all(|c| c.is_digit(10)) && !text.is_empty() {
self.cores = text.parse::<usize>().unwrap();
break;
}
}
let memory_output = match Command::new("wmic")
.args(&["memorychip", "get", "capacity"])
.output() {
Ok(e) => e,
Err(e) => {
return Err(format!("Failed to get memory info: {}", e.to_string()));
}
};
let memory_info = String::from_utf8_lossy(&memory_output.stdout);
let mut total_memory: u64 = 0;
for line in memory_info.lines() {
let text = line.trim();
if text.chars().all(|c| c.is_digit(10)) && !text.is_empty() {
if let Ok(capacity) = text.parse::<u64>() {
total_memory += capacity;
}
}
}
self.memory = format!("{} GB", total_memory / 1024u64.pow(3));
let uuid_output = match Command::new("powershell")
.args(&["Get-WmiObject", "Win32_DiskDrive", "|", "Select-Object", "-ExpandProperty", "Signature"])
.output() {
Ok(e) => e,
Err(e) => {
return Err(format!("Failed to get disk UUIDs: {}", e.to_string()));
}
};
let uuid = String::from_utf8_lossy(&uuid_output.stdout);
for line in uuid.lines() {
let text = line.trim();
if !text.is_empty() {
self.hardware_uuid = text.to_string();
break;
}
}
Ok(self)
}
}