pyc_shell/config/
configparser.rs1extern crate yaml_rust;
27
28use super::{ConfigError, ConfigErrorCode};
29use yaml_rust::Yaml;
30
31pub struct ConfigParser {}
33
34impl ConfigParser {
35 pub fn get_child(yaml_doc: &Yaml, child: String) -> Result<&Yaml, ConfigError> {
39 match yaml_doc[child.as_str()].is_badvalue() {
40 true => Err(ConfigError {
41 code: ConfigErrorCode::YamlSyntaxError,
42 message: String::from(format!("Missing key '{}'", child)),
43 }),
44 false => Ok(&yaml_doc[child.as_str()]),
45 }
46 }
47
48 pub fn get_bool(yaml_doc: &Yaml, key: String) -> Result<bool, ConfigError> {
52 match ConfigParser::get_child(&yaml_doc, key.clone()) {
53 Ok(child) => match child.as_bool() {
54 Some(v) => Ok(v),
55 None => Err(ConfigError {
56 code: ConfigErrorCode::YamlSyntaxError,
57 message: String::from(format!("'{}' is not a bool", key)),
58 }),
59 },
60 Err(err) => Err(err),
61 }
62 }
63
64 pub fn get_usize(yaml_doc: &Yaml, key: String) -> Result<usize, ConfigError> {
68 match ConfigParser::get_child(&yaml_doc, key.clone()) {
69 Ok(child) => match child.as_i64() {
70 Some(v) => Ok(v as usize),
71 None => Err(ConfigError {
72 code: ConfigErrorCode::YamlSyntaxError,
73 message: String::from(format!("'{}' is not a number", key)),
74 }),
75 },
76 Err(err) => Err(err),
77 }
78 }
79
80 pub fn get_string(yaml_doc: &Yaml, key: String) -> Result<String, ConfigError> {
84 match ConfigParser::get_child(&yaml_doc, key.clone()) {
85 Ok(child) => match child.as_str() {
86 Some(s) => Ok(String::from(s)),
87 None => Err(ConfigError {
88 code: ConfigErrorCode::YamlSyntaxError,
89 message: String::from(format!("'{}' is not a string", key)),
90 }),
91 },
92 Err(err) => Err(err),
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use yaml_rust::{Yaml, YamlLoader};
101
102 #[test]
103 fn test_configparser_yaml_parser() {
104 let yaml_doc: Yaml = gen_sample_yaml();
105 let sample_doc: &Yaml = ConfigParser::get_child(&yaml_doc, String::from("sample")).ok().unwrap();
106 assert_eq!(ConfigParser::get_usize(&sample_doc, String::from("usize")).ok().unwrap(), 2048);
108 assert_eq!(ConfigParser::get_bool(&sample_doc, String::from("bool")).ok().unwrap(), true);
110 assert_eq!(ConfigParser::get_string(&sample_doc, String::from("str")).ok().unwrap(), String::from("foobar"));
112 assert!(ConfigParser::get_child(&sample_doc, String::from("array")).is_ok());
114 assert!(ConfigParser::get_child(&sample_doc, String::from("map")).is_ok());
115 }
116
117 #[test]
118 fn test_configparser_yaml_bad_values() {
119 let yaml_doc: Yaml = gen_sample_yaml();
120 let sample_doc: &Yaml = ConfigParser::get_child(&yaml_doc, String::from("sample")).ok().unwrap();
121 assert!(ConfigParser::get_bool(&sample_doc, String::from("str")).is_err());
122 assert!(ConfigParser::get_usize(&sample_doc, String::from("str")).is_err());
123 assert!(ConfigParser::get_string(&sample_doc, String::from("array")).is_err());
124 assert!(ConfigParser::get_child(&sample_doc, String::from("foobar")).is_err());
125 }
126
127 fn gen_sample_yaml() -> Yaml {
128 let sample: String = String::from("sample:\n usize: 2048\n bool: true\n str: \"foobar\"\n array:\n - 1\n - 2\n - 3\n map:\n foo: true\n bar: \"pluto\"\n");
129 println!("{}", sample.clone());
130 match YamlLoader::load_from_str(sample.as_str()) {
131 Ok(mut doc) => doc.pop().unwrap(),
132 Err(_) => {
133 panic!("Could not parse YAML");
134 }
135 }
136 }
137}