insta/content/yaml/
mod.rs
1pub mod vendored;
2
3use std::path::Path;
4
5use crate::content::{Content, Error};
6
7use crate::content::yaml::vendored::{yaml::Hash as YamlObj, Yaml as YamlValue};
8
9pub fn parse_str(s: &str, filename: &Path) -> Result<Content, Error> {
10 let mut blobs = crate::content::yaml::vendored::yaml::YamlLoader::load_from_str(s)
11 .map_err(|_| Error::FailedParsingYaml(filename.to_path_buf()))?;
12
13 match (blobs.pop(), blobs.pop()) {
14 (Some(blob), None) => from_yaml_blob(blob, filename),
15 _ => Err(Error::FailedParsingYaml(filename.to_path_buf())),
16 }
17}
18
19fn from_yaml_blob(blob: YamlValue, filename: &Path) -> Result<Content, Error> {
20 match blob {
21 YamlValue::Null => Ok(Content::None),
22 YamlValue::Boolean(b) => Ok(Content::from(b)),
23 YamlValue::Integer(num) => Ok(Content::from(num)),
24 YamlValue::Real(real_str) => {
25 let real: f64 = real_str.parse().unwrap();
26 Ok(Content::from(real))
27 }
28 YamlValue::String(s) => Ok(Content::from(s)),
29 YamlValue::Array(seq) => {
30 let seq = seq
31 .into_iter()
32 .map(|x| from_yaml_blob(x, filename))
33 .collect::<Result<_, Error>>()?;
34 Ok(Content::Seq(seq))
35 }
36 YamlValue::Hash(obj) => {
37 let obj = obj
38 .into_iter()
39 .map(|(k, v)| Ok((from_yaml_blob(k, filename)?, from_yaml_blob(v, filename)?)))
40 .collect::<Result<_, Error>>()?;
41 Ok(Content::Map(obj))
42 }
43 YamlValue::BadValue => Err(Error::FailedParsingYaml(filename.to_path_buf())),
44 }
45}
46
47pub fn to_string(content: &Content) -> String {
48 let yaml_blob = to_yaml_value(content);
49
50 let mut buf = String::new();
51 let mut emitter = crate::content::yaml::vendored::emitter::YamlEmitter::new(&mut buf);
52 emitter.dump(&yaml_blob).unwrap();
53
54 if !buf.ends_with('\n') {
55 buf.push('\n');
56 }
57 buf
58}
59
60fn to_yaml_value(content: &Content) -> YamlValue {
61 fn translate_seq(seq: &[Content]) -> YamlValue {
62 let seq = seq.iter().map(to_yaml_value).collect();
63 YamlValue::Array(seq)
64 }
65
66 fn translate_fields(fields: &[(&str, Content)]) -> YamlValue {
67 let fields = fields
68 .iter()
69 .map(|(k, v)| (YamlValue::String(k.to_string()), to_yaml_value(v)))
70 .collect();
71 YamlValue::Hash(fields)
72 }
73
74 match content {
75 Content::Bool(b) => YamlValue::Boolean(*b),
76 Content::U8(n) => YamlValue::Integer(i64::from(*n)),
77 Content::U16(n) => YamlValue::Integer(i64::from(*n)),
78 Content::U32(n) => YamlValue::Integer(i64::from(*n)),
79 Content::U64(n) => YamlValue::Real(n.to_string()),
80 Content::U128(n) => YamlValue::Real(n.to_string()),
81 Content::I8(n) => YamlValue::Integer(i64::from(*n)),
82 Content::I16(n) => YamlValue::Integer(i64::from(*n)),
83 Content::I32(n) => YamlValue::Integer(i64::from(*n)),
84 Content::I64(n) => YamlValue::Integer(*n),
85 Content::I128(n) => YamlValue::Real(n.to_string()),
86 Content::F32(f) => YamlValue::Real(f.to_string()),
87 Content::F64(f) => YamlValue::Real(f.to_string()),
88 Content::Char(c) => YamlValue::String(c.to_string()),
89 Content::String(s) => YamlValue::String(s.to_owned()),
90 Content::Bytes(bytes) => {
91 let bytes = bytes
92 .iter()
93 .map(|b| YamlValue::Integer(i64::from(*b)))
94 .collect();
95 YamlValue::Array(bytes)
96 }
97 Content::None | Content::Unit | Content::UnitStruct(_) => YamlValue::Null,
98 Content::Some(content) => to_yaml_value(content),
99 Content::UnitVariant(_, _, variant) => YamlValue::String(variant.to_string()),
100 Content::NewtypeStruct(_, content) => to_yaml_value(content),
101 Content::NewtypeVariant(_, _, variant, content) => {
102 let mut obj = YamlObj::new();
103 obj.insert(
104 YamlValue::String(variant.to_string()),
105 to_yaml_value(content),
106 );
107 YamlValue::Hash(obj)
108 }
109 Content::Seq(seq) => translate_seq(seq),
110 Content::Tuple(seq) => translate_seq(seq),
111 Content::TupleStruct(_, seq) => translate_seq(seq),
112 Content::TupleVariant(_, _, variant, seq) => {
113 let mut obj = YamlObj::new();
114 obj.insert(YamlValue::String(variant.to_string()), translate_seq(seq));
115 YamlValue::Hash(obj)
116 }
117 Content::Map(map) => {
118 let map = map
119 .iter()
120 .map(|(k, v)| (to_yaml_value(k), to_yaml_value(v)))
121 .collect();
122
123 YamlValue::Hash(map)
124 }
125 Content::Struct(_name, fields) => translate_fields(fields),
126 Content::StructVariant(_, _, variant, fields) => {
127 let mut obj = YamlObj::new();
128 obj.insert(
129 YamlValue::String(variant.to_string()),
130 translate_fields(fields),
131 );
132 YamlValue::Hash(obj)
133 }
134 }
135}