substrait_validator/input/
yaml.rs1use crate::output::diagnostic;
12use crate::output::path;
13use crate::output::primitive_data;
14use crate::output::tree;
15use crate::parse::traversal;
16
17use serde_yaml::value::Value as Yaml;
18
19pub type Value = serde_json::value::Value;
21
22pub type Array = Vec<Value>;
24
25pub type Map = serde_json::map::Map<String, Value>;
27
28pub fn yaml_to_json(y: Yaml, path: &path::Path) -> diagnostic::DiagResult<Value> {
31 match y {
32 Yaml::Null => Ok(Value::Null),
33 Yaml::Bool(b) => Ok(Value::Bool(b)),
34 Yaml::Number(n) => {
35 if let Some(u) = n.as_u64() {
36 Ok(Value::Number(u.into()))
37 } else if let Some(i) = n.as_i64() {
38 Ok(Value::Number(i.into()))
39 } else if let Some(f) = n.as_f64() {
40 Ok(Value::Number(
41 serde_json::value::Number::from_f64(f).ok_or_else(|| {
42 diag!(
43 path.to_path_buf(),
44 Error,
45 YamlParseFailed,
46 "{f} float is not supported"
47 )
48 })?,
49 ))
50 } else {
51 panic!("encountered serde_yaml::number::Number that cannot be represented as u64, i64, of f64");
52 }
53 }
54 Yaml::String(s) => Ok(Value::String(s)),
55 Yaml::Sequence(a) => Ok(Value::Array(
56 a.into_iter()
57 .enumerate()
58 .map(|(index, value)| yaml_to_json(value, &path.with_index(index)))
59 .collect::<diagnostic::DiagResult<Vec<Value>>>()?,
60 )),
61 Yaml::Mapping(m) => Ok(Value::Object(
62 m.into_iter()
63 .map(|(key, value)| {
64 let key = key
65 .as_str()
66 .ok_or_else(|| {
67 diag!(
68 path.to_path_buf(),
69 Error,
70 YamlParseFailed,
71 "non-string map keys are not supported"
72 )
73 })?
74 .to_string();
75 let path = path.with_field(&key);
76 let value = yaml_to_json(value, &path)?;
77 Ok((key, value))
78 })
79 .collect::<diagnostic::DiagResult<serde_json::value::Map<String, Value>>>()?,
80 )),
81 Yaml::Tagged(_) => Err(diag!(
82 path.to_path_buf(),
83 Error,
84 YamlParseFailed,
85 "YAML tagged values are not supported"
86 )),
87 }
88}
89
90impl crate::input::traits::InputNode for Value {
91 fn type_to_node() -> tree::Node {
92 tree::NodeType::YamlMap.into()
93 }
94
95 fn data_to_node(&self) -> tree::Node {
96 match self {
97 Value::Null => tree::NodeType::YamlPrimitive(primitive_data::PrimitiveData::Null),
98 Value::Bool(b) => {
99 tree::NodeType::YamlPrimitive(primitive_data::PrimitiveData::Bool(*b))
100 }
101 Value::Number(n) => tree::NodeType::YamlPrimitive(
102 n.as_u64()
103 .map(primitive_data::PrimitiveData::Unsigned)
104 .or_else(|| n.as_i64().map(primitive_data::PrimitiveData::Signed))
105 .or_else(|| n.as_f64().map(primitive_data::PrimitiveData::Float))
106 .unwrap(),
107 ),
108 Value::String(s) => {
109 tree::NodeType::YamlPrimitive(primitive_data::PrimitiveData::String(s.clone()))
110 }
111 Value::Array(_) => tree::NodeType::YamlArray,
112 Value::Object(_) => tree::NodeType::YamlMap,
113 }
114 .into()
115 }
116
117 fn oneof_variant(&self) -> Option<&'static str> {
118 None
119 }
120
121 fn parse_unknown(&self, context: &mut crate::parse::context::Context<'_>) -> bool {
122 match self {
123 Value::Array(array) => {
124 let mut any = false;
125 for (index, _) in array.iter().enumerate() {
126 if !context.field_parsed(index.to_string()) {
127 traversal::push_yaml_element(array, context, index, true, |_, _| Ok(()));
128 any = true;
129 }
130 }
131 any
132 }
133 Value::Object(object) => {
134 let mut any = false;
135 let mut keys: Vec<_> = object.keys().collect();
136 keys.sort();
137 for field_name in keys {
138 if !context.field_parsed(field_name) {
139 traversal::push_yaml_field(self, context, field_name, true, |_, _| Ok(()))
140 .unwrap();
141 any = true;
142 }
143 }
144 any
145 }
146 _ => false,
147 }
148 }
149}