From d394daefc660e622715528a8e1ea504ff645e130 Mon Sep 17 00:00:00 2001 From: dormant-user Date: Sat, 21 Sep 2024 12:27:56 -0500 Subject: [PATCH] Add docstrings and restructure code --- src/squire/mod.rs | 2 + src/squire/settings.rs | 4 +- src/squire/util.rs | 87 +++++++++++++++++++++++++++++++++++++ src/system_info/mod.rs | 2 + src/system_info/network.rs | 79 ++++++++++++++++++++------------- src/system_info/sys_info.rs | 81 +++++++++++++++------------------- src/templates/error.rs | 3 +- src/templates/session.rs | 3 +- 8 files changed, 179 insertions(+), 82 deletions(-) create mode 100644 src/squire/util.rs diff --git a/src/squire/mod.rs b/src/squire/mod.rs index 7aecf1f..c6c5551 100644 --- a/src/squire/mod.rs +++ b/src/squire/mod.rs @@ -14,3 +14,5 @@ pub mod custom; pub mod authenticator; /// Module for the functions that handle encryption/encoding and decryption/decoding. pub mod secure; +/// Module for utility functions. +pub mod util; diff --git a/src/squire/settings.rs b/src/squire/settings.rs index ee9aac0..c847e62 100644 --- a/src/squire/settings.rs +++ b/src/squire/settings.rs @@ -52,8 +52,8 @@ pub fn default_host() -> String { /// Returns the default port (8000) pub fn default_port() -> u16 { 8000 } -/// Returns the default session duration (3600 seconds) -pub fn default_session_duration() -> i64 { 3600 } +/// Returns the default session duration (900 seconds) +pub fn default_session_duration() -> i64 { 900 } /// Returns the default number of worker threads (half of logical cores) pub fn default_workers() -> usize { diff --git a/src/squire/util.rs b/src/squire/util.rs new file mode 100644 index 0000000..551c442 --- /dev/null +++ b/src/squire/util.rs @@ -0,0 +1,87 @@ +use regex::Regex; +use std::collections::HashMap; + +/// Function to retrieve the REGEX object for an IPv4 address format +/// +/// # Returns +/// +/// A `Regex` object that can be used to match an IPv4 address format +pub fn ip_regex() -> Regex { + Regex::new( + r"^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$" + ).unwrap() +} + +/// Mapping of URLs to check for public IP addresses +/// +/// # Returns +/// +/// A `HashMap` containing the URL and a boolean value indicating whether the URL expects text or JSON response +pub fn public_ip_mapping() -> HashMap { + let mapping: HashMap = vec![ + ("https://checkip.amazonaws.com/".to_string(), true), // expects text + ("https://api.ipify.org/".to_string(), true), // expects text + ("https://ipinfo.io/ip/".to_string(), true), // expects text + ("https://v4.ident.me/".to_string(), true), // expects text + ("https://httpbin.org/ip".to_string(), false), // expects JSON + ("https://myip.dnsomatic.com/".to_string(), true), // expects text + ] + .into_iter() + .collect(); + mapping +} + + +/// Function to convert seconds to human-readable format +/// +/// # Arguments +/// +/// * `seconds` - The number of seconds to convert +/// +/// # Returns +/// +/// A `String` containing the human-readable format of the seconds +pub fn convert_seconds(seconds: i64) -> String { + let days = seconds / 86_400; // 86,400 seconds in a day + let hours = (seconds % 86_400) / 3_600; // 3,600 seconds in an hour + let minutes = (seconds % 3_600) / 60; // 60 seconds in a minute + let remaining_seconds = seconds % 60; + + let mut result = Vec::new(); + + if days > 0 { + result.push(format!("{} day{}", days, if days > 1 { "s" } else { "" })); + } + if hours > 0 { + result.push(format!("{} hour{}", hours, if hours > 1 { "s" } else { "" })); + } + if minutes > 0 && result.len() < 2 { + result.push(format!("{} minute{}", minutes, if minutes > 1 { "s" } else { "" })); + } + if remaining_seconds > 0 && result.len() < 2 { + result.push(format!("{} second{}", remaining_seconds, if remaining_seconds > 1 { "s" } else { "" })); + } + result.join(" and ") +} + +/// 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]) +} diff --git a/src/system_info/mod.rs b/src/system_info/mod.rs index 703f015..470ca67 100644 --- a/src/system_info/mod.rs +++ b/src/system_info/mod.rs @@ -1,2 +1,4 @@ +/// This module contains all the system information related functions pub mod sys_info; +/// This module contains all the network related functions pub mod network; diff --git a/src/system_info/network.rs b/src/system_info/network.rs index 38a2b4c..41709e0 100644 --- a/src/system_info/network.rs +++ b/src/system_info/network.rs @@ -1,31 +1,19 @@ -use regex::Regex; use reqwest; use serde::{Deserialize, Serialize}; -use std::net::{SocketAddr, UdpSocket}; +use std::net::UdpSocket; +use crate::squire; -// Define the IP regex pattern -fn ip_regex() -> Regex { - Regex::new( - r"^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$" - ).unwrap() -} - -// Synchronous function to retrieve the public IP address +/// Function to retrieve the public IP address +/// +/// # Returns +/// +/// An `Option` containing the public IP address as a `String` if found, otherwise `None` async fn public_ip_address() -> Option { - let ip_regex = ip_regex(); - - // Mapping URLs to their expected response types - let mapping: Vec<(&str, bool)> = vec![ - ("https://checkip.amazonaws.com/", true), // expects text - ("https://api.ipify.org/", true), // expects text - ("https://ipinfo.io/ip/", true), // expects text - ("https://v4.ident.me/", true), // expects text - ("https://httpbin.org/ip", false), // expects JSON - ("https://myip.dnsomatic.com/", true), // expects text - ]; + let ip_regex = squire::util::ip_regex(); + let mapping = squire::util::public_ip_mapping(); for (url, expects_text) in mapping { - match reqwest::get(url).await { + match reqwest::get(&url).await { Ok(response) => { let extracted_ip = if expects_text { response.text().await.unwrap_or_default().trim().to_string() @@ -39,8 +27,8 @@ async fn public_ip_address() -> Option { return Some(extracted_ip); } } - Err(e) => { - eprintln!("Failed to fetch from {}: {}", url, e); + Err(err) => { + log::error!("Failed to fetch from {}: {}", &url, err); continue; // Move on to the next URL } } @@ -49,21 +37,54 @@ async fn public_ip_address() -> Option { None } -// Function to retrieve the private IP address +/// Function to retrieve the private IP address +/// +/// # Returns +/// +/// An `Option` containing the private IP address as a `String` if found, otherwise `None` fn private_ip_address() -> Option { - let socket = UdpSocket::bind("0.0.0.0:0").ok()?; - socket.connect("8.8.8.8:80").ok()?; - let local_addr: SocketAddr = socket.local_addr().ok()?; + let socket = match UdpSocket::bind("0.0.0.0:0") { + Ok(s) => s, + Err(err) => { + log::error!("Failed to bind to a socket: {}", err); + return None; + } + }; + if socket.connect("8.8.8.8:80").is_err() { + log::error!("Failed to connect to a socket"); + return None; + } + let local_addr = match socket.local_addr() { + Ok(addr) => addr, + Err(err) => { + log::error!("Failed to get local IP address: {}", err); + return None; + } + }; Some(local_addr.ip().to_string()) } +/// Struct to hold the network information of the system +/// +/// This struct holds the private and public IP addresses of the system. +/// +/// # Fields +/// +/// * `private_ip_address` - The private IP address of the system +/// * `public_ip_address` - The public IP address of the system #[derive(Serialize, Deserialize, Debug)] pub struct SystemInfoNetwork { private_ip_address: String, public_ip_address: String, } - +/// Function to get network information +/// +/// This function retrieves the private and public IP addresses of the system. +/// +/// # Returns +/// +/// A `SystemInfoNetwork` struct containing the private and public IP addresses. pub async fn get_network_info() -> SystemInfoNetwork { let private_ip = private_ip_address().unwrap_or_default(); let public_ip = public_ip_address().await.unwrap_or_default(); diff --git a/src/system_info/sys_info.rs b/src/system_info/sys_info.rs index fbc6f83..410bd24 100644 --- a/src/system_info/sys_info.rs +++ b/src/system_info/sys_info.rs @@ -1,46 +1,19 @@ use chrono::Utc; use serde::{Deserialize, Serialize}; use sysinfo::{DiskExt, System, SystemExt}; +use crate::squire; -// Helper function to format the duration -fn convert_seconds(seconds: i64) -> String { - let days = seconds / 86_400; // 86,400 seconds in a day - let hours = (seconds % 86_400) / 3_600; // 3,600 seconds in an hour - let minutes = (seconds % 3_600) / 60; // 60 seconds in a minute - let remaining_seconds = seconds % 60; - - let mut result = Vec::new(); - - if days > 0 { - result.push(format!("{} day{}", days, if days > 1 { "s" } else { "" })); - } - if hours > 0 { - result.push(format!("{} hour{}", hours, if hours > 1 { "s" } else { "" })); - } - if minutes > 0 && result.len() < 2 { - result.push(format!("{} minute{}", minutes, if minutes > 1 { "s" } else { "" })); - } - if remaining_seconds > 0 && result.len() < 2 { - result.push(format!("{} second{}", remaining_seconds, if remaining_seconds > 1 { "s" } else { "" })); - } - result.join(" and ") -} - -// Helper function to convert size -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]) -} - -// Struct to hold system information in a JSON-serializable format +/// Struct to hold basic system information +/// +/// This struct holds basic system information such as the node name, system name, architecture, CPU cores, and uptime. +/// +/// # Fields +/// +/// * `node` - The node name of the system +/// * `system` - The system name +/// * `architecture` - The system architecture +/// * `cpu_cores` - The number of CPU cores +/// * `uptime` - The system uptime #[derive(Serialize, Deserialize, Debug)] pub struct SystemInfoBasic { node: String, @@ -50,6 +23,15 @@ pub struct SystemInfoBasic { uptime: String, } +/// Struct to hold memory and storage information +/// +/// This struct holds memory and storage information such as the total memory, total swap, and total storage. +/// +/// # Fields +/// +/// * `memory` - The total memory of the system +/// * `swap` - The total swap space of the system +/// * `storage` - The total storage space of the system #[derive(Serialize, Deserialize, Debug)] pub struct SystemInfoMemStorage { memory: String, @@ -57,8 +39,13 @@ pub struct SystemInfoMemStorage { storage: String, } - -// Function to collect system information and return as a JSON-serializable struct +/// Function to get system information +/// +/// This function retrieves system information such as basic system information and memory/storage information. +/// +/// # Returns +/// +/// A tuple containing the `SystemInfoBasic` and `SystemInfoMemStorage` structs. pub fn get_sys_info() -> (SystemInfoBasic, SystemInfoMemStorage) { let mut sys = System::new_all(); sys.refresh_all(); @@ -66,16 +53,16 @@ pub fn get_sys_info() -> (SystemInfoBasic, SystemInfoMemStorage) { // Uptime let boot_time = sys.boot_time(); let uptime_duration = Utc::now().timestamp() - boot_time as i64; - let uptime = convert_seconds(uptime_duration); + let uptime = squire::util::convert_seconds(uptime_duration); - let total_memory = size_converter(sys.total_memory()); // in bytes - let total_swap = size_converter(sys.total_swap()); // in bytes - let total_storage = size_converter(sys.disks().iter().map(|disk| disk.total_space()).sum::()); + let total_memory = squire::util::size_converter(sys.total_memory()); // in bytes + let total_swap = squire::util::size_converter(sys.total_swap()); // in bytes + let total_storage = squire::util::size_converter(sys.disks().iter().map(|disk| disk.total_space()).sum::()); // Basic and Memory/Storage Info let basic = SystemInfoBasic { - node: sys.host_name().unwrap_or_else(|| "Unknown".to_string()), - system: sys.name().unwrap_or_else(|| "Unknown".to_string()), + node: sys.host_name().unwrap_or("Unknown".to_string()), + system: sys.name().unwrap_or("Unknown".to_string()), architecture: std::env::consts::ARCH.to_string(), uptime, cpu_cores: sys.cpus().len().to_string(), diff --git a/src/templates/error.rs b/src/templates/error.rs index 4ad1590..9a5690d 100644 --- a/src/templates/error.rs +++ b/src/templates/error.rs @@ -2,8 +2,7 @@ /// /// # See Also /// -/// - This page is served as a response for all the entry points, -/// when the user tries to access a page without valid authentication. +/// This page is served as a response, when the user tries to access a page without valid authentication. /// /// # Returns /// diff --git a/src/templates/session.rs b/src/templates/session.rs index a2491cf..f66f619 100644 --- a/src/templates/session.rs +++ b/src/templates/session.rs @@ -2,8 +2,7 @@ /// /// # See Also /// -/// - This page is served as a response for all the content delivery entry points, -/// when the user's `session_token` is invalid or expired. +/// This page is served as a response when the user's `session_token` is invalid or expired. /// /// # Returns ///