Parse a memory size value that can be decimal or hexadecimal (with 0x prefix) Supports the following formats: - Plain numbers: "1024", "2048" - Hexadecimal: "0x1000", "0X2000" - With suffixes: "2K", "4M", "1G", "2T" (case-insensitive) Suffixes use binary (1024-based) multipliers: - K/k: 1024 bytes - M/m: 1024^2 bytes - G/g: 1024^3 bytes - T/t: 1024^4 bytes
(s: &str)
| 103 | /// - G/g: 1024^3 bytes |
| 104 | /// - T/t: 1024^4 bytes |
| 105 | pub fn parse(s: &str) -> Result<Self, MemorySizeError> { |
| 106 | let s = s.trim(); |
| 107 | |
| 108 | if s.is_empty() { |
| 109 | return Err(MemorySizeError::Empty); |
| 110 | } |
| 111 | |
| 112 | // Handle hexadecimal values |
| 113 | if s.starts_with("0x") || s.starts_with("0X") { |
| 114 | let hex_str = &s[2..]; |
| 115 | let bytes = u64::from_str_radix(hex_str, 16) |
| 116 | .map_err(|_| MemorySizeError::InvalidHex(hex_str.to_string()))?; |
| 117 | return Ok(Self::from_bytes(bytes)); |
| 118 | } |
| 119 | |
| 120 | // Handle plain numbers (all digits) |
| 121 | if s.chars().all(|c| c.is_ascii_digit()) { |
| 122 | let bytes = s |
| 123 | .parse::<u64>() |
| 124 | .map_err(|_| MemorySizeError::InvalidNumber(s.to_string()))?; |
| 125 | return Ok(Self::from_bytes(bytes)); |
| 126 | } |
| 127 | |
| 128 | // Handle numbers with suffixes |
| 129 | let Some(last_char) = s.chars().last() else { |
| 130 | return Err(MemorySizeError::Empty); |
| 131 | }; |
| 132 | |
| 133 | let multiplier = match last_char.to_ascii_lowercase() { |
| 134 | 'k' => 1024u64, |
| 135 | 'm' => 1024u64.saturating_mul(1024), |
| 136 | 'g' => 1024u64.saturating_mul(1024).saturating_mul(1024), |
| 137 | 't' => 1024u64 |
| 138 | .saturating_mul(1024) |
| 139 | .saturating_mul(1024) |
| 140 | .saturating_mul(1024), |
| 141 | _ => return Err(MemorySizeError::UnknownSuffix(last_char)), |
| 142 | }; |
| 143 | let num_part = s.trim_end_matches(last_char); |
| 144 | let num = num_part |
| 145 | .parse::<u64>() |
| 146 | .map_err(|_| MemorySizeError::InvalidNumber(num_part.to_string()))?; |
| 147 | |
| 148 | let bytes = num |
| 149 | .checked_mul(multiplier) |
| 150 | .ok_or(MemorySizeError::Overflow)?; |
| 151 | |
| 152 | Ok(Self::from_bytes(bytes)) |
| 153 | } |
| 154 | |
| 155 | /// Format the memory size in a human-readable way |
| 156 | pub fn format_human(&self) -> String { |