json_eval_rs/jsoneval/
getters.rs1use super::JSONEval;
2use crate::jsoneval::path_utils;
3use crate::jsoneval::types::ReturnFormat;
4
5
6
7use serde_json::Value;
8use crate::time_block;
9
10
11impl JSONEval {
12 pub fn get_evaluated_schema(&mut self, skip_layout: bool) -> Value {
22 time_block!("get_evaluated_schema()", {
23 if !skip_layout {
24 if let Err(e) = self.resolve_layout(false) {
25 eprintln!("Warning: Layout resolution failed in get_evaluated_schema: {}", e);
26 }
27 }
28 self.evaluated_schema.clone()
29 })
30 }
31
32
33
34 pub fn get_schema_value_by_path(&self, path: &str) -> Option<Value> {
36 let pointer_path = path_utils::dot_notation_to_schema_pointer(path);
37 self.evaluated_schema.pointer(&pointer_path).cloned()
38 }
39
40 pub fn get_schema_value(&mut self) -> Value {
44 let mut current_data = self.eval_data.data().clone();
46
47 if !current_data.is_object() {
49 current_data = Value::Object(serde_json::Map::new());
50 }
51
52 for eval_key in self.value_evaluations.iter() {
55 let clean_key = eval_key.replace('#', "");
56
57 if clean_key.starts_with("/$params")
59 || (clean_key.ends_with("/value")
60 && (clean_key.contains("/rules/") || clean_key.contains("/options/")))
61 {
62 continue;
63 }
64
65 let path = clean_key.replace("/properties", "").replace("/value", "");
66
67 let value = match self.evaluated_schema.pointer(&clean_key) {
69 Some(v) => v.clone(),
70 None => continue,
71 };
72
73 let path_parts: Vec<&str> = path.split('/').filter(|s| !s.is_empty()).collect();
75
76 if path_parts.is_empty() {
77 continue;
78 }
79
80 let mut current = &mut current_data;
82 for (i, part) in path_parts.iter().enumerate() {
83 let is_last = i == path_parts.len() - 1;
84
85 if is_last {
86 if let Some(obj) = current.as_object_mut() {
88 obj.insert(part.to_string(), crate::utils::clean_float_noise(value.clone()));
89 }
90 } else {
91 if let Some(obj) = current.as_object_mut() {
93 if !obj.contains_key(*part) {
99 obj.insert((*part).to_string(), Value::Object(serde_json::Map::new()));
100 }
101
102 current = obj.get_mut(*part).unwrap();
103 } else {
104 break;
106 }
107 }
108 }
109 }
110
111 self.data = current_data.clone();
113
114 crate::utils::clean_float_noise(current_data)
115 }
116
117 pub fn get_evaluated_schema_without_params(&mut self, skip_layout: bool) -> Value {
119 let mut schema = self.get_evaluated_schema(skip_layout);
120 if let Value::Object(ref mut map) = schema {
121 map.remove("$params");
122 }
123 schema
124 }
125
126 pub fn get_evaluated_schema_msgpack(&mut self, skip_layout: bool) -> Result<Vec<u8>, String> {
128 let schema = self.get_evaluated_schema(skip_layout);
129 rmp_serde::to_vec(&schema).map_err(|e| format!("MessagePack serialization failed: {}", e))
130 }
131
132 pub fn get_evaluated_schema_by_path(&mut self, path: &str, skip_layout: bool) -> Option<Value> {
134 if !skip_layout {
135 if let Err(e) = self.resolve_layout(false) {
136 eprintln!("Warning: Layout resolution failed in get_evaluated_schema_by_path: {}", e);
137 }
138 }
139 self.get_schema_value_by_path(path)
140 }
141
142 pub fn get_evaluated_schema_by_paths(
144 &mut self,
145 paths: &[String],
146 skip_layout: bool,
147 format: Option<ReturnFormat>,
148 ) -> Value {
149 if !skip_layout {
150 if let Err(e) = self.resolve_layout(false) {
151 eprintln!("Warning: Layout resolution failed in get_evaluated_schema_by_paths: {}", e);
152 }
153 }
154
155 match format.unwrap_or(ReturnFormat::Nested) {
156 ReturnFormat::Nested => {
157 let mut result = Value::Object(serde_json::Map::new());
158 for path in paths {
159 if let Some(val) = self.get_schema_value_by_path(path) {
160 Self::insert_at_path(&mut result, path, val);
162 }
163 }
164 result
165 }
166 ReturnFormat::Flat => {
167 let mut result = serde_json::Map::new();
168 for path in paths {
169 if let Some(val) = self.get_schema_value_by_path(path) {
170 result.insert(path.clone(), val);
171 }
172 }
173 Value::Object(result)
174 }
175 ReturnFormat::Array => {
176 let mut result = Vec::new();
177 for path in paths {
178 if let Some(val) = self.get_schema_value_by_path(path) {
179 result.push(val);
180 } else {
181 result.push(Value::Null);
182 }
183 }
184 Value::Array(result)
185 }
186 }
187 }
188
189 pub fn get_schema_by_path(&self, path: &str) -> Option<Value> {
191 let pointer_path = path_utils::dot_notation_to_schema_pointer(path);
192 self.schema.pointer(&pointer_path).cloned()
193 }
194
195 pub fn get_schema_by_paths(
197 &self,
198 paths: &[String],
199 format: Option<ReturnFormat>,
200 ) -> Value {
201 match format.unwrap_or(ReturnFormat::Nested) {
202 ReturnFormat::Nested => {
203 let mut result = Value::Object(serde_json::Map::new());
204 for path in paths {
205 if let Some(val) = self.get_schema_by_path(path) {
206 Self::insert_at_path(&mut result, path, val);
207 }
208 }
209 result
210 }
211 ReturnFormat::Flat => {
212 let mut result = serde_json::Map::new();
213 for path in paths {
214 if let Some(val) = self.get_schema_by_path(path) {
215 result.insert(path.clone(), val);
216 }
217 }
218 Value::Object(result)
219 }
220 ReturnFormat::Array => {
221 let mut result = Vec::new();
222 for path in paths {
223 if let Some(val) = self.get_schema_by_path(path) {
224 result.push(val);
225 } else {
226 result.push(Value::Null);
227 }
228 }
229 Value::Array(result)
230 }
231 }
232 }
233
234 pub(crate) fn insert_at_path(root: &mut Value, path: &str, value: Value) {
236 let parts: Vec<&str> = path.split('.').collect();
237 let mut current = root;
238
239 for (i, part) in parts.iter().enumerate() {
240 if i == parts.len() - 1 {
241 if let Value::Object(map) = current {
243 map.insert(part.to_string(), value);
244 return; }
246 } else {
247 if !current.is_object() {
252 *current = Value::Object(serde_json::Map::new());
253 }
254
255 if let Value::Object(map) = current {
256 if !map.contains_key(*part) {
257 map.insert(part.to_string(), Value::Object(serde_json::Map::new()));
258 }
259 current = map.get_mut(*part).unwrap();
260 }
261 }
262 }
263 }
264
265 pub fn flatten_object(prefix: &str, value: &Value, result: &mut serde_json::Map<String, Value>) {
267 match value {
268 Value::Object(map) => {
269 for (k, v) in map {
270 let new_key = if prefix.is_empty() {
271 k.clone()
272 } else {
273 format!("{}.{}", prefix, k)
274 };
275 Self::flatten_object(&new_key, v, result);
276 }
277 }
278 _ => {
279 result.insert(prefix.to_string(), value.clone());
280 }
281 }
282 }
283
284 pub fn convert_to_format(value: Value, format: ReturnFormat) -> Value {
285 match format {
286 ReturnFormat::Nested => value,
287 ReturnFormat::Flat => {
288 let mut result = serde_json::Map::new();
289 Self::flatten_object("", &value, &mut result);
290 Value::Object(result)
291 }
292 ReturnFormat::Array => {
293 if let Value::Object(map) = value {
297 Value::Array(map.values().cloned().collect())
298 } else if let Value::Array(arr) = value {
299 Value::Array(arr)
300 } else {
301 Value::Array(vec![value])
302 }
303 }
304 }
305 }
306}