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}