diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-06-08 00:55:42 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-06-08 00:55:42 -0400 |
commit | 2dad06cae3991d7de819f39cf7d63f8e2b519aca (patch) | |
tree | 9354fa7fc9b570114e7f82d759bf49070ff723b5 /src/parse.rs | |
download | leak_memory-2dad06cae3991d7de819f39cf7d63f8e2b519aca.tar.gz leak_memory-2dad06cae3991d7de819f39cf7d63f8e2b519aca.tar.bz2 leak_memory-2dad06cae3991d7de819f39cf7d63f8e2b519aca.zip |
initial
Diffstat (limited to '')
-rw-r--r-- | src/parse.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/parse.rs b/src/parse.rs new file mode 100644 index 0000000..edfd9c5 --- /dev/null +++ b/src/parse.rs @@ -0,0 +1,71 @@ +use std::str::FromStr; +use crate::{error::PissError, PissAmount}; + +impl<T> From<T> for PissAmount +where T: Into<u128> { + fn from(num: T) -> PissAmount { + PissAmount { + to_piss: num.into() + } + } +} + +fn parse_suffix(s: &str) -> Result<u128, PissError> { + Ok(match s { // nepal + "k" | "kb" => 1_000, + "m" | "mb" => 1_000_000, + "g" | "gb" => 1_000_000_000, + "t" | "tb" => 1_000_000_000_000, + "p" | "pb" => 1_000_000_000_000_000, + "e" | "eb" => 1_000_000_000_000_000_000, + "x" | "xb" => 1_000_000_000_000_000_000_000, + "y" | "yb" => 1_000_000_000_000_000_000_000_000, + "r" | "rb" => 1_000_000_000_000_000_000_000_000_000, + "q" | "qb" => 1_000_000_000_000_000_000_000_000_000_000, + "ki" | "kib" => 0x400, + "mi" | "mib" => 0x100000, + "gi" | "gib" => 0x40000000, + "ti" | "tib" => 0x10000000000, + "pi" | "pib" => 0x4000000000000, + "ei" | "eib" => 0x1000000000000000, + "xi" | "xib" => 0x400000000000000000, + "yi" | "yib" => 0x100000000000000000000, + "ri" | "rib" => 0x40000000000000000000000, + "qi" | "qib" => 0x10000000000000000000000000, + "" | "b" => 1, // uwu + _ => return Err(PissError::InvalidSuffix(s.into())) // such nepal + }) +} + +fn parse_file_size(s: &str) -> Result<PissAmount, PissError> { + let mut end = 0; + for (i, c) in s.char_indices() { + if c.is_digit(10) || c == '.' { continue; } + end = i; + break; + } + + let num_text = &s[..end]; + let suffix_text = &s[end..]; + + let Ok(num) = num_text.parse::<f64>() else { + return Err(PissError::InvalidNumber(num_text.into())) + }; + + if num <= 0f64 { + return Err(PissError::NumberNotPositive) + } + + let multiplier = parse_suffix(suffix_text)?; + + Ok(PissAmount { + to_piss: (num * multiplier as f64) as u128 + }) +} + +impl FromStr for PissAmount { + type Err = PissError; + fn from_str(s: &str) -> Result<Self, Self::Err> { + parse_file_size(s) + } +} |