Skip to content

Commit

Permalink
Add deprecated functions as placeholder
Browse files Browse the repository at this point in the history
  • Loading branch information
vsivanandharao committed Sep 26, 2024
1 parent f777fea commit 1b59010
Show file tree
Hide file tree
Showing 6 changed files with 404 additions and 5 deletions.
99 changes: 99 additions & 0 deletions src/deprecated/cpu_brand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use std::fs::File;
use std::io::{self, BufRead};

use crate::deprecated::helper::run_command;

/// Function to get processor information.
///
/// # Arguments
///
/// * `lib_path` - The path to the library used to get processor information.
///
/// # Returns
///
/// A `Option` containing the processor information if successful, otherwise `None`.
fn get_processor_info_darwin(lib_path: &str) -> Result<String, &'static str> {
let result = run_command(lib_path, &["-n", "machdep.cpu.brand_string"]);
if result.is_err() {
return Err("Failed to get processor info");
}
Ok(result.unwrap())
}

/// Function to get processor information on Linux.
///
/// # Arguments
///
/// * `lib_path` - The path to the library used to get processor information.
///
/// # Returns
///
/// A `Option` containing the processor information if successful, otherwise `None`.
fn get_processor_info_linux(lib_path: &str) -> Result<String, &'static str> {
let file = match File::open(lib_path) {
Ok(file) => file,
Err(_) => return Err("Failed to open file"),
};
for line in io::BufReader::new(file).lines() {
match line {
Ok(line) => {
if line.contains("model name") {
let parts: Vec<&str> = line.split(':').collect();
if parts.len() == 2 {
return Ok(parts[1].trim().to_string());
}
}
}
Err(_) => return Err("Error reading line"),
}
}
Err("Model name not found")
}

/// Function to get processor information on Windows.
///
/// # Arguments
///
/// * `lib_path` - The path to the library used to get processor information.
///
/// # Returns
///
/// A `Option` containing the processor information if successful, otherwise `None`.
fn get_processor_info_windows(lib_path: &str) -> Result<String, &'static str> {
let result = run_command(lib_path, &["cpu", "get", "name"]);
let output = match result {
Ok(output) => output,
Err(_) => return Err("Failed to get processor info"),
};
let lines: Vec<&str> = output.trim().split('\n').collect();
if lines.len() > 1 {
Ok(lines[1].trim().to_string())
} else {
Err("Invalid output from command")
}
}

/// OS-agnostic function to get processor name.
///
/// # Returns
///
/// A `Option` containing the processor name if successful, otherwise `None`.
pub fn get_name() -> Option<String> {
let operating_system = std::env::consts::OS;
let result = match operating_system {
"darwin" => get_processor_info_darwin("/usr/sbin/sysctl"),
"linux" => get_processor_info_linux("/proc/cpuinfo"),
"windows" => get_processor_info_windows("C:\\Windows\\System32\\wbem\\wmic.exe"),
_ => {
log::error!("Unsupported operating system: {}", operating_system);
Err("Unsupported operating system")
}
};
match result {
Ok(info) => Some(info),
Err(err) => {
log::error!("{}", err);
None
}
}
}
224 changes: 224 additions & 0 deletions src/deprecated/disks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
use std::collections::HashMap;
use std::str;
use regex::Regex;
use serde_json::Value;

use crate::deprecated::helper::{run_command, size_converter};

/// Function to parse size string for Linux.
///
/// # Arguments
///
/// * `size_str` - The size string to parse
///
/// # Returns
///
/// A `String` containing the parsed size string.
fn parse_size(size_str: &str) -> String {
let re = Regex::new(r"([\d.]+)([KMGTP]?)").unwrap();
if let Some(caps) = re.captures(size_str.trim()) {
let value: f64 = caps[1].parse().unwrap();
let unit = &caps[2];
let unit_multipliers = HashMap::from([
("K", 2_f64.powi(10)),
("M", 2_f64.powi(20)),
("G", 2_f64.powi(30)),
("T", 2_f64.powi(40)),
("P", 2_f64.powi(50)),
]);
let multiplier = unit_multipliers.get(unit).unwrap_or(&1.0);
return size_converter((value * multiplier) as u64);
}
size_str.replace("K", " KB")
.replace("M", " MB")
.replace("G", " GB")
.replace("T", " TB")
.replace("P", " PB")
}

/// Function to check if a disk is physical/virtual for macOS.
///
/// # Arguments
///
/// * `lib_path` - The path to the library
/// * `device_id` - The device ID
///
/// # Returns
///
/// A `bool` indicating if the disk is physical.
fn is_physical_disk(lib_path: &str, device_id: &str) -> bool {
let result = run_command(lib_path, &["info", device_id]);
let output = match result {
Ok(output) => output,
Err(_) => {
log::error!("Failed to get disk info");
return false;
},
};
for line in output.split("\n") {
if line.contains("Virtual:") && line.contains("Yes") {
return false;
}
}
true
}

/// Function to get disk information on Linux.
///
/// # Arguments
///
/// * `lib_path` - The path to the library used to get disks' information.
///
/// # Returns
///
/// A `Vec` of `HashMap` containing the disk information.
fn linux_disks(lib_path: &str) -> Vec<HashMap<String, String>> {
let result = run_command(lib_path, &["-o", "NAME,SIZE,TYPE,MODEL", "-d"]);
let output = match result {
Ok(output) => output,
Err(_) => {
log::error!("Failed to get disk info");
return Vec::new();
},
};
let disks: Vec<&str> = output.lines().collect();
let filtered_disks: Vec<&str> = disks.into_iter().filter(|&disk| !disk.contains("loop")).collect();
let keys_raw = filtered_disks[0].to_lowercase()
.replace("name", "DeviceID")
.replace("model", "Name")
.replace("size", "Size");
let keys: Vec<&str> = keys_raw.split_whitespace().collect();
let mut disk_info = Vec::new();
for line in &filtered_disks[1..] {
let values: Vec<&str> = line.split_whitespace().collect();
let mut disk_map = HashMap::new();
for (key, value) in keys.iter().zip(values.iter()) {
disk_map.insert(key.to_string(), value.to_string());
}
disk_map.insert("Size".to_string(), parse_size(disk_map.get("Size").unwrap()));
disk_map.remove("type");
disk_info.push(disk_map);
}
disk_info
}

/// Function to get disk information on macOS.
///
/// # Arguments
///
/// * `lib_path` - The path to the library used to get disks' information.
///
/// # Returns
///
/// A `Vec` of `HashMap` containing the disk information.
fn darwin_disks(lib_path: &str) -> Vec<HashMap<String, String>> {
let result = run_command(lib_path, &["list"]);
let output = match result {
Ok(output) => output,
Err(_) => {
log::error!("Failed to get disk info");
return Vec::new();
},
};
let disks: Vec<&str> = output.lines().collect();
let disk_lines: Vec<&str> = disks.into_iter().filter(|&line| line.starts_with("/dev/disk")).collect();
let mut disk_info = Vec::new();
for line in disk_lines {
let device_id = line.split_whitespace().next().unwrap();
if !is_physical_disk(lib_path, device_id) {
continue;
}
let result = run_command(lib_path, &["info", device_id]);
let disk_info_output = match result {
Ok(output) => output,
Err(_) => {
log::error!("Failed to get disk info");
return Vec::new();
},
};
let info_lines: Vec<&str> = disk_info_output.lines().collect();
let mut disk_data = HashMap::new();
for info_line in info_lines {
if info_line.contains("Device / Media Name:") {
disk_data.insert("Name".to_string(), info_line.split(":").nth(1).unwrap().trim().to_string());
}
if info_line.contains("Disk Size:") {
let size_info = info_line.split(":").nth(1).unwrap().split("(").next().unwrap().trim().to_string();
disk_data.insert("Size".to_string(), size_info);
}
}
disk_data.insert("DeviceID".to_string(), device_id.to_string());
disk_info.push(disk_data);
}
disk_info
}

/// Function to reformat disk information on Windows.
///
/// # Arguments
///
/// * `data` - A mutable reference to the disk information.
///
/// # Returns
///
/// A `HashMap` containing the reformatted disk information.
fn reformat_windows(data: &mut HashMap<String, Value>) -> HashMap<String, String> {
let size = data.get("Size").unwrap().as_f64().unwrap();
let model = data.get("Model").unwrap().as_str().unwrap().to_string();
let mut reformatted_data = HashMap::new();
reformatted_data.insert("Size".to_string(), size_converter(size as u64));
reformatted_data.insert("Name".to_string(), model);
reformatted_data.insert("DeviceID".to_string(), data.get("DeviceID").unwrap().as_str().unwrap().to_string());
reformatted_data
}

/// Function to get disk information on Windows.
///
/// # Arguments
///
/// * `lib_path` - The path to the library used to get disks' information.
///
/// # Returns
///
/// A `Vec` of `HashMap` containing the disk information.
fn windows_disks(lib_path: &str) -> Vec<HashMap<String, String>> {
let ps_command = "Get-CimInstance Win32_DiskDrive | Select-Object Caption, DeviceID, Model, Partitions, Size | ConvertTo-Json";
let result = run_command(lib_path, &["-Command", ps_command]);
let output = match result {
Ok(output) => output,
Err(_) => {
log::error!("Failed to get disk info");
return Vec::new();
},
};
let disks_info: Value = serde_json::from_str(&output).unwrap();
let mut disk_info = Vec::new();
if let Some(disks) = disks_info.as_array() {
for disk in disks {
let mut disk_map: HashMap<String, Value> = serde_json::from_value(disk.clone()).unwrap();
disk_info.push(reformat_windows(&mut disk_map));
}
} else {
let mut disk_map: HashMap<String, Value> = serde_json::from_value(disks_info).unwrap();
disk_info.push(reformat_windows(&mut disk_map));
}
disk_info
}

/// Function to get all disks' information.
///
/// # Returns
///
/// A `Vec` of `HashMap` containing the disk information.
pub fn get_all_disks() -> Vec<HashMap<String, String>> {
let operating_system = std::env::consts::OS;
match operating_system {
"windows" => windows_disks("C:\\Program Files\\PowerShell\\7\\pwsh.exe"),
"macos" => darwin_disks("/usr/sbin/diskutil"),
"linux" => linux_disks("/usr/bin/lsblk"),
_ => {
log::error!("Unsupported operating system");
Vec::new()
}
}
}
58 changes: 58 additions & 0 deletions src/deprecated/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use std::process::Command;

/// Function to convert byte size to human-readable format
///
/// # Arguments
///
/// * `byte_size` - The size in bytes to convert
///
/// # Returns
///
/// A `String` containing the human-readable format of the byte size
pub fn size_converter(byte_size: u64) -> String {
let size_name = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
let mut index = 0;
let mut size = byte_size as f64;

while size >= 1024.0 && index < size_name.len() - 1 {
size /= 1024.0;
index += 1;
}

format!("{:.2} {}", size, size_name[index])
}


/// Function to parse size string.
///
/// # Arguments
///
/// * `size_str` - The size string to parse
/// * `unit` - The unit to convert the size to
///
/// # Returns
///
/// A `String` containing the parsed size string.
pub fn run_command(command: &str, args: &[&str]) -> Result<String, String> {
match Command::new(command)
.args(args)
.output()
{
Ok(output) => {
if output.status.success() {
log::debug!("Command [{}] executed successfully", &command);
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
} else {
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let exit_code = output.status.code().unwrap_or(-1);
log::error!("Command [{}] failed with exit code: {}", command, exit_code);
log::error!("Stderr: {}", stderr);
Err(stderr)
}
}
Err(err) => {
log::error!("Failed to execute command: {}", err);
Err(err.to_string())
}
}
}
Loading

0 comments on commit 1b59010

Please sign in to comment.