xref: /aosp_15_r20/system/librustutils/system_properties/parsers_formatters.rs (revision e51878c104ea269309bae357ae559a9fff179380)
1 //! Parsers and formatters.
2 //!
3 //! These functions should only be used in the system properties generated code.
4 
5 use std::str::FromStr;
6 use std::string::ToString;
7 
8 type Result<T> = std::result::Result<T, String>;
9 
10 // Parsers.
11 
12 /// Parses the given string as a `T`, or returns an error including the string value.
parse<T: FromStr>(s: &str) -> Result<T>13 pub fn parse<T: FromStr>(s: &str) -> Result<T> {
14     s.parse::<T>()
15         .map_err(|_| format!("Can't convert '{}' to '{}'.", s, std::any::type_name::<T>()))
16 }
17 
18 /// Parses the given string as a boolean or returns an error message including the string.
19 ///
20 /// `true` and `1` are both considered true, `false` and `0` are false. Any other value is invalid.
parse_bool(s: &str) -> Result<bool>21 pub fn parse_bool(s: &str) -> Result<bool> {
22     match s {
23         "1" | "true" => Ok(true),
24         "0" | "false" => Ok(false),
25         _ => Err(format!("Can't convert '{}' to 'bool'.", s)),
26     }
27 }
28 
parse_list_with<T, F>(s: &str, f: F) -> Result<Vec<T>> where F: Fn(&str) -> Result<T>,29 fn parse_list_with<T, F>(s: &str, f: F) -> Result<Vec<T>>
30 where
31     F: Fn(&str) -> Result<T>,
32 {
33     let mut result = Vec::new();
34     if s.is_empty() {
35         return Ok(result);
36     }
37 
38     let mut chars = s.chars();
39     let mut current = chars.next();
40     while current.is_some() {
41         // Extract token.
42         let mut token = String::with_capacity(s.len());
43         while let Some(value) = current {
44             if value == ',' {
45                 break;
46             }
47             if value == '\\' {
48                 current = chars.next()
49             }
50             if let Some(value) = current {
51                 token.push(value);
52             }
53             current = chars.next();
54         }
55         // Parse token.
56         result.push(f(token.as_str())?);
57         current = chars.next()
58     }
59 
60     Ok(result)
61 }
62 
63 /// Parses the given string as a comma-separated list of `T`s.
64 ///
65 /// Literal commas can be escaped with `\`.
parse_list<T: FromStr>(s: &str) -> Result<Vec<T>>66 pub fn parse_list<T: FromStr>(s: &str) -> Result<Vec<T>> {
67     parse_list_with(s, parse)
68 }
69 
70 /// Parses the given string as a comma-separated list of booleans.
71 ///
72 /// Literal commas can be escaped with `\`.
parse_bool_list(s: &str) -> Result<Vec<bool>>73 pub fn parse_bool_list(s: &str) -> Result<Vec<bool>> {
74     parse_list_with(s, parse_bool)
75 }
76 
77 // Formatters.
78 
79 /// Converts the given value to a string.
format<T: ToString>(v: &T) -> String80 pub fn format<T: ToString>(v: &T) -> String {
81     v.to_string()
82 }
83 
84 /// Converts the given value to a string `true` or `false`.
format_bool(v: &bool) -> String85 pub fn format_bool(v: &bool) -> String {
86     if *v {
87         return "true".into();
88     }
89     "false".into()
90 }
91 
92 /// Converts the given value to a string `1` or `0`.
format_bool_as_int(v: &bool) -> String93 pub fn format_bool_as_int(v: &bool) -> String {
94     if *v {
95         return "1".into();
96     }
97     "0".into()
98 }
99 
format_list_with<T, F>(v: &[T], f: F) -> String where F: Fn(&T) -> String,100 fn format_list_with<T, F>(v: &[T], f: F) -> String
101 where
102     F: Fn(&T) -> String,
103 {
104     let mut result = String::new();
105     for item in v {
106         let formatted = f(item);
107         result.push_str(formatted.as_str());
108         result.push(',');
109     }
110     result.pop();
111     result
112 }
113 
114 /// Converts the given list of values to a string, separated by commas.
format_list<T: ToString>(v: &[T]) -> String115 pub fn format_list<T: ToString>(v: &[T]) -> String {
116     format_list_with(v, format)
117 }
118 
119 /// Converts the given list of booleans to a string, separated by commas.
format_bool_list(v: &[bool]) -> String120 pub fn format_bool_list(v: &[bool]) -> String {
121     format_list_with(v, format_bool)
122 }
123 
124 /// Converts the given list of booleans to a string of `0`s and `1`s separated by commas.
format_bool_list_as_int(v: &[bool]) -> String125 pub fn format_bool_list_as_int(v: &[bool]) -> String {
126     format_list_with(v, format_bool_as_int)
127 }
128