##// END OF EJS Templates
rust: Move config value parsing functions to a new module...
Simon Sapin -
r47344:a687a7f2 default
parent child Browse files
Show More
@@ -0,0 +1,43 b''
1 //! Parsing functions for various type of configuration values.
2 //!
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,
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
7 //! those options to results with `ConfigValueParseError`, which contains
8 //! details about where the value came from (but omits details of what’s
9 //! invalid inside the value).
10
11 pub(super) fn parse_bool(v: &[u8]) -> Option<bool> {
12 match v.to_ascii_lowercase().as_slice() {
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),
15 _ => None,
16 }
17 }
18
19 pub(super) fn parse_byte_size(value: &[u8]) -> Option<u64> {
20 let value = std::str::from_utf8(value).ok()?.to_ascii_lowercase();
21 const UNITS: &[(&str, u64)] = &[
22 ("g", 1 << 30),
23 ("gb", 1 << 30),
24 ("m", 1 << 20),
25 ("mb", 1 << 20),
26 ("k", 1 << 10),
27 ("kb", 1 << 10),
28 ("b", 1 << 0), // Needs to be last
29 ];
30 for &(unit, multiplier) in UNITS {
31 // TODO: use `value.strip_suffix(unit)` when we require Rust 1.45+
32 if value.ends_with(unit) {
33 let value_before_unit = &value[..value.len() - unit.len()];
34 let float: f64 = value_before_unit.trim().parse().ok()?;
35 if float >= 0.0 {
36 return Some((float * multiplier as f64).round() as u64);
37 } else {
38 return None;
39 }
40 }
41 }
42 value.parse().ok()
43 }
@@ -11,5 +11,6 b''
11
11
12 mod config;
12 mod config;
13 mod layer;
13 mod layer;
14 mod values;
14 pub use config::{Config, ConfigValueParseError};
15 pub use config::{Config, ConfigValueParseError};
15 pub use layer::{ConfigError, ConfigParseError};
16 pub use layer::{ConfigError, ConfigParseError};
@@ -8,6 +8,7 b''
8 // GNU General Public License version 2 or any later version.
8 // GNU General Public License version 2 or any later version.
9
9
10 use super::layer;
10 use super::layer;
11 use super::values;
11 use crate::config::layer::{
12 use crate::config::layer::{
12 ConfigError, ConfigLayer, ConfigOrigin, ConfigValue,
13 ConfigError, ConfigLayer, ConfigOrigin, ConfigValue,
13 };
14 };
@@ -64,40 +65,6 b' pub struct ConfigValueParseError {'
64 pub expected_type: &'static str,
65 pub expected_type: &'static str,
65 }
66 }
66
67
67 pub fn parse_bool(v: &[u8]) -> Option<bool> {
68 match v.to_ascii_lowercase().as_slice() {
69 b"1" | b"yes" | b"true" | b"on" | b"always" => Some(true),
70 b"0" | b"no" | b"false" | b"off" | b"never" => Some(false),
71 _ => None,
72 }
73 }
74
75 pub fn parse_byte_size(value: &[u8]) -> Option<u64> {
76 let value = str::from_utf8(value).ok()?.to_ascii_lowercase();
77 const UNITS: &[(&str, u64)] = &[
78 ("g", 1 << 30),
79 ("gb", 1 << 30),
80 ("m", 1 << 20),
81 ("mb", 1 << 20),
82 ("k", 1 << 10),
83 ("kb", 1 << 10),
84 ("b", 1 << 0), // Needs to be last
85 ];
86 for &(unit, multiplier) in UNITS {
87 // TODO: use `value.strip_suffix(unit)` when we require Rust 1.45+
88 if value.ends_with(unit) {
89 let value_before_unit = &value[..value.len() - unit.len()];
90 let float: f64 = value_before_unit.trim().parse().ok()?;
91 if float >= 0.0 {
92 return Some((float * multiplier as f64).round() as u64);
93 } else {
94 return None;
95 }
96 }
97 }
98 value.parse().ok()
99 }
100
101 impl Config {
68 impl Config {
102 /// Load system and user configuration from various files.
69 /// Load system and user configuration from various files.
103 ///
70 ///
@@ -324,7 +291,7 b' impl Config {'
324 section: &[u8],
291 section: &[u8],
325 item: &[u8],
292 item: &[u8],
326 ) -> Result<Option<u64>, ConfigValueParseError> {
293 ) -> Result<Option<u64>, ConfigValueParseError> {
327 self.get_parse(section, item, "byte quantity", parse_byte_size)
294 self.get_parse(section, item, "byte quantity", values::parse_byte_size)
328 }
295 }
329
296
330 /// Returns an `Err` if the first value found is not a valid boolean.
297 /// Returns an `Err` if the first value found is not a valid boolean.
@@ -335,7 +302,7 b' impl Config {'
335 section: &[u8],
302 section: &[u8],
336 item: &[u8],
303 item: &[u8],
337 ) -> Result<Option<bool>, ConfigValueParseError> {
304 ) -> Result<Option<bool>, ConfigValueParseError> {
338 self.get_parse(section, item, "boolean", parse_bool)
305 self.get_parse(section, item, "boolean", values::parse_bool)
339 }
306 }
340
307
341 /// Returns the corresponding boolean in the config. Returns `Ok(false)`
308 /// Returns the corresponding boolean in the config. Returns `Ok(false)`
General Comments 0
You need to be logged in to leave comments. Login now