aboutsummaryrefslogtreecommitdiff
path: root/vendor/number_prefix/src/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/number_prefix/src/parse.rs')
-rw-r--r--vendor/number_prefix/src/parse.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/vendor/number_prefix/src/parse.rs b/vendor/number_prefix/src/parse.rs
new file mode 100644
index 0000000..cfb37af
--- /dev/null
+++ b/vendor/number_prefix/src/parse.rs
@@ -0,0 +1,87 @@
+use std::{error::Error, fmt, str};
+
+use super::{NumberPrefix, Prefix};
+
+
+impl<T: str::FromStr> str::FromStr for NumberPrefix<T> {
+ type Err = NumberPrefixParseError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let splitted = s.find(|p| {
+ p == 'k' || p == 'K' || p == 'M' || p == 'G' || p == 'T' ||
+ p == 'P' || p == 'E' || p == 'Z' || p == 'Y'
+ });
+
+ let num_prefix = s.split_at(splitted.unwrap_or(s.len()));
+ let num = match num_prefix.0.trim().parse::<T>() {
+ Ok(n) => n,
+ Err(_) => return Err(NumberPrefixParseError(())),
+ };
+
+ let prefix_unit = num_prefix.1.trim_matches(|p|
+ p == 'b' || p == 'B' || p == 'm'
+ );
+
+ let prefix = match prefix_unit {
+ "k" |
+ "K" => Prefix::Kilo,
+ "M" => Prefix::Mega,
+ "G" => Prefix::Giga,
+ "T" => Prefix::Tera,
+ "P" => Prefix::Peta,
+ "E" => Prefix::Exa,
+ "Z" => Prefix::Zetta,
+ "Y" => Prefix::Yotta,
+ "Ki" => Prefix::Kibi,
+ "Mi" => Prefix::Mebi,
+ "Gi" => Prefix::Gibi,
+ "Ti" => Prefix::Tebi,
+ "Pi" => Prefix::Pebi,
+ "Ei" => Prefix::Exbi,
+ "Zi" => Prefix::Zebi,
+ "Yi" => Prefix::Yobi,
+ "" => return Ok(NumberPrefix::Standalone(num)),
+ _ => return Err(NumberPrefixParseError(())),
+ };
+
+ Ok(NumberPrefix::Prefixed(prefix, num))
+ }
+}
+
+
+/// The error returned when a `NumberPrefix` is failed to be parsed.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct NumberPrefixParseError(());
+
+impl fmt::Display for NumberPrefixParseError {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.write_str("invalid prefix syntax")
+ }
+}
+
+impl Error for NumberPrefixParseError {
+}
+
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn parse_examples() {
+ let parse_example_a = "7.05E".parse::<NumberPrefix<f64>>();
+ let parse_example_b = "7.05".parse::<NumberPrefix<f64>>();
+ let parse_example_c = "7.05 GiB".parse::<NumberPrefix<f64>>();
+
+ assert_eq!(parse_example_a, Ok(NumberPrefix::Prefixed(Prefix::Exa, 7.05_f64)));
+ assert_eq!(parse_example_b, Ok(NumberPrefix::Standalone(7.05_f64)));
+ assert_eq!(parse_example_c, Ok(NumberPrefix::Prefixed(Prefix::Gibi, 7.05_f64)));
+ }
+
+ #[test]
+ fn bad_parse() {
+ let parsed = "bogo meters per second".parse::<NumberPrefix<f64>>();
+
+ assert_ne!(parsed, Ok(NumberPrefix::Prefixed(Prefix::Kilo, 7.05_f64)));
+ }
+}