shapely_yaml/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use shapely_core::Partial;
4use yaml_rust2::YamlLoader;
5
6/// Deserializes YAML data into a Shapely Partial.
7///
8/// # Example
9///
10/// ```
11/// use shapely::Shapely;
12/// use shapely_yaml::from_yaml;
13///
14/// #[derive(Debug, Shapely, PartialEq)]
15/// struct Config {
16///     name: String,
17///     version: u64,
18/// }
19///
20/// let yaml = r#"
21/// name: MyApp
22/// version: 1
23/// "#;
24///
25/// let mut partial = Config::partial();
26/// from_yaml(&mut partial, yaml).expect("Failed to parse YAML");
27///
28/// let config = partial.build::<Config>();
29/// assert_eq!(config, Config { name: "MyApp".to_string(), version: 1 });
30/// ```
31pub fn from_yaml(partial: &mut Partial, yaml: &str) -> Result<(), String> {
32    let docs = YamlLoader::load_from_str(yaml).map_err(|e| e.to_string())?;
33
34    // Assuming only one document in the YAML string
35    let doc = &docs[0];
36    match doc {
37        yaml_rust2::Yaml::Hash(hash) => {
38            for (key, value) in hash {
39                let key_str = match key.as_str() {
40                    Some(s) => s,
41                    None => return Err("Expected string key".to_string()),
42                };
43
44                let slot = partial
45                    .slot_by_name(key_str)
46                    .map_err(|_| format!("Unknown field: {}", key_str))?;
47
48                match value {
49                    yaml_rust2::Yaml::String(s) => {
50                        slot.fill(s.clone());
51                    }
52                    yaml_rust2::Yaml::Integer(i) => {
53                        slot.fill(*i as u64);
54                    }
55                    _ => {
56                        println!("Unsupported YAML type for field: {}", key_str);
57                        unimplemented!()
58                    }
59                }
60            }
61        }
62        _ => {
63            return Err("Expected a YAML hash".to_string());
64        }
65    }
66
67    Ok(())
68}
69
70#[cfg(test)]
71mod tests {
72    #[test]
73    fn it_works() {
74        assert_eq!(2 + 2, 4);
75    }
76}