##// END OF EJS Templates
rust: Add some unit tests for parse_byte_size in config...
Simon Sapin -
r47345:1b7c0b10 default
parent child Browse files
Show More
@@ -1,43 +1,61 b''
1 //! Parsing functions for various type of configuration values.
1 //! Parsing functions for various type of configuration values.
2 //!
2 //!
3 //! Returning `None` indicates a syntax error. Using a `Result` would be more
3 //! Returning `None` indicates a syntax error. Using a `Result` would be more
4 //! correct but would take more boilerplate for converting between error types,
4 //! correct but would take more boilerplate for converting between error types,
5 //! compared to using `.ok()` on inner results of various error types to
5 //! compared to using `.ok()` on inner results of various error types to
6 //! convert them all to options. The `Config::get_parse` method later converts
6 //! convert them all to options. The `Config::get_parse` method later converts
7 //! those options to results with `ConfigValueParseError`, which contains
7 //! those options to results with `ConfigValueParseError`, which contains
8 //! details about where the value came from (but omits details of what’s
8 //! details about where the value came from (but omits details of what’s
9 //! invalid inside the value).
9 //! invalid inside the value).
10
10
11 pub(super) fn parse_bool(v: &[u8]) -> Option<bool> {
11 pub(super) fn parse_bool(v: &[u8]) -> Option<bool> {
12 match v.to_ascii_lowercase().as_slice() {
12 match v.to_ascii_lowercase().as_slice() {
13 b"1" | b"yes" | b"true" | b"on" | b"always" => Some(true),
13 b"1" | b"yes" | b"true" | b"on" | b"always" => Some(true),
14 b"0" | b"no" | b"false" | b"off" | b"never" => Some(false),
14 b"0" | b"no" | b"false" | b"off" | b"never" => Some(false),
15 _ => None,
15 _ => None,
16 }
16 }
17 }
17 }
18
18
19 pub(super) fn parse_byte_size(value: &[u8]) -> Option<u64> {
19 pub(super) fn parse_byte_size(value: &[u8]) -> Option<u64> {
20 let value = std::str::from_utf8(value).ok()?.to_ascii_lowercase();
20 let value = std::str::from_utf8(value).ok()?.to_ascii_lowercase();
21 const UNITS: &[(&str, u64)] = &[
21 const UNITS: &[(&str, u64)] = &[
22 ("g", 1 << 30),
22 ("g", 1 << 30),
23 ("gb", 1 << 30),
23 ("gb", 1 << 30),
24 ("m", 1 << 20),
24 ("m", 1 << 20),
25 ("mb", 1 << 20),
25 ("mb", 1 << 20),
26 ("k", 1 << 10),
26 ("k", 1 << 10),
27 ("kb", 1 << 10),
27 ("kb", 1 << 10),
28 ("b", 1 << 0), // Needs to be last
28 ("b", 1 << 0), // Needs to be last
29 ];
29 ];
30 for &(unit, multiplier) in UNITS {
30 for &(unit, multiplier) in UNITS {
31 // TODO: use `value.strip_suffix(unit)` when we require Rust 1.45+
31 // TODO: use `value.strip_suffix(unit)` when we require Rust 1.45+
32 if value.ends_with(unit) {
32 if value.ends_with(unit) {
33 let value_before_unit = &value[..value.len() - unit.len()];
33 let value_before_unit = &value[..value.len() - unit.len()];
34 let float: f64 = value_before_unit.trim().parse().ok()?;
34 let float: f64 = value_before_unit.trim().parse().ok()?;
35 if float >= 0.0 {
35 if float >= 0.0 {
36 return Some((float * multiplier as f64).round() as u64);
36 return Some((float * multiplier as f64).round() as u64);
37 } else {
37 } else {
38 return None;
38 return None;
39 }
39 }
40 }
40 }
41 }
41 }
42 value.parse().ok()
42 value.parse().ok()
43 }
43 }
44
45 #[test]
46 fn test_parse_byte_size() {
47 assert_eq!(parse_byte_size(b""), None);
48 assert_eq!(parse_byte_size(b"b"), None);
49
50 assert_eq!(parse_byte_size(b"12"), Some(12));
51 assert_eq!(parse_byte_size(b"12b"), Some(12));
52 assert_eq!(parse_byte_size(b"12 b"), Some(12));
53 assert_eq!(parse_byte_size(b"12.1 b"), Some(12));
54 assert_eq!(parse_byte_size(b"1.1 K"), Some(1126));
55 assert_eq!(parse_byte_size(b"1.1 kB"), Some(1126));
56
57 assert_eq!(parse_byte_size(b"-12 b"), None);
58 assert_eq!(parse_byte_size(b"-0.1 b"), None);
59 assert_eq!(parse_byte_size(b"0.1 b"), Some(0));
60 assert_eq!(parse_byte_size(b"12.1 b"), Some(12));
61 }
General Comments 0
You need to be logged in to leave comments. Login now