Parse a human-readable memory size string into bytes. Supported formats: - `"512MiB"` / `"512M"` → mebibytes (base-1024) - `"8GiB"` / `"8G"` → gibibytes (base-1024) - `"1073741824"` → raw bytes (no suffix) Matching is case-insensitive on the suffix.
(s: &str)
| 13 | /// |
| 14 | /// Matching is case-insensitive on the suffix. |
| 15 | pub fn parse_memory_size(s: &str) -> crate::Result<usize> { |
| 16 | let s = s.trim(); |
| 17 | if s.is_empty() { |
| 18 | return Err(crate::Error::Config { |
| 19 | detail: "empty string".to_string(), |
| 20 | }); |
| 21 | } |
| 22 | |
| 23 | let split_pos = s.find(|c: char| !c.is_ascii_digit()).unwrap_or(s.len()); |
| 24 | |
| 25 | let (num_part, suffix) = s.split_at(split_pos); |
| 26 | let suffix = suffix.trim(); |
| 27 | |
| 28 | let cfg = |detail: String| crate::Error::Config { detail }; |
| 29 | |
| 30 | let base: u64 = num_part |
| 31 | .parse() |
| 32 | .map_err(|_| cfg(format!("invalid number: {num_part}")))?; |
| 33 | |
| 34 | let bytes: u64 = match suffix.to_ascii_uppercase().as_str() { |
| 35 | "" => base, |
| 36 | "B" => base, |
| 37 | "K" | "KB" | "KIB" => base |
| 38 | .checked_mul(1024) |
| 39 | .ok_or_else(|| cfg(format!("overflow parsing memory size: {s}")))?, |
| 40 | "M" | "MB" | "MIB" => base |
| 41 | .checked_mul(1024 * 1024) |
| 42 | .ok_or_else(|| cfg(format!("overflow parsing memory size: {s}")))?, |
| 43 | "G" | "GB" | "GIB" => base |
| 44 | .checked_mul(1024 * 1024 * 1024) |
| 45 | .ok_or_else(|| cfg(format!("overflow parsing memory size: {s}")))?, |
| 46 | "T" | "TB" | "TIB" => base |
| 47 | .checked_mul(1024 * 1024 * 1024 * 1024) |
| 48 | .ok_or_else(|| cfg(format!("overflow parsing memory size: {s}")))?, |
| 49 | other => { |
| 50 | return Err(cfg(format!("unknown memory size suffix: '{other}'"))); |
| 51 | } |
| 52 | }; |
| 53 | |
| 54 | usize::try_from(bytes).map_err(|_| cfg(format!("memory size too large for this platform: {s}"))) |
| 55 | } |
| 56 | |
| 57 | /// Parse a u16 port from an env var into a required field. |
| 58 | fn apply_port_env(var: &str, target: &mut u16) { |