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.trim_start_matches('#')).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 if let Some(obj) = current_data.as_object_mut() {
54 obj.remove("$params");
55 obj.remove("$context");
56 }
57
58 for eval_key in self.value_evaluations.iter() {
61 let clean_key = eval_key.replace('#', "");
62
63 if clean_key.starts_with("/$params")
65 || (clean_key.ends_with("/value")
66 && (clean_key.contains("/rules/") || clean_key.contains("/options/")))
67 {
68 continue;
69 }
70
71 let path = clean_key.replace("/properties", "").replace("/value", "");
72
73 let value = match self.evaluated_schema.pointer(&clean_key) {
75 Some(v) => v.clone(),
76 None => continue,
77 };
78
79 let path_parts: Vec<&str> = path.split('/').filter(|s| !s.is_empty()).collect();
81
82 if path_parts.is_empty() {
83 continue;
84 }
85
86 let mut current = &mut current_data;
88 for (i, part) in path_parts.iter().enumerate() {
89 let is_last = i == path_parts.len() - 1;
90
91 if is_last {
92 if let Some(obj) = current.as_object_mut() {
94 obj.insert(part.to_string(), crate::utils::clean_float_noise(value.clone()));
95 }
96 } else {
97 if let Some(obj) = current.as_object_mut() {
99 if !obj.contains_key(*part) {
105 obj.insert((*part).to_string(), Value::Object(serde_json::Map::new()));
106 }
107
108 current = obj.get_mut(*part).unwrap();
109 } else {
110 break;
112 }
113 }
114 }
115 }
116
117 self.data = current_data.clone();
119
120 crate::utils::clean_float_noise(current_data)
121 }
122
123 pub fn get_schema_value_array(&self) -> Value {
130 let mut result = Vec::new();
131
132 for eval_key in self.value_evaluations.iter() {
133 let clean_key = eval_key.replace('#', "");
134
135 if clean_key.starts_with("/$params")
137 || (clean_key.ends_with("/value")
138 && (clean_key.contains("/rules/") || clean_key.contains("/options/")))
139 {
140 continue;
141 }
142
143 let dotted_path = clean_key
145 .replace("/properties", "")
146 .replace("/value", "")
147 .trim_start_matches('/')
148 .replace('/', ".");
149
150 if dotted_path.is_empty() {
151 continue;
152 }
153
154 let value = match self.evaluated_schema.pointer(&clean_key) {
156 Some(v) => crate::utils::clean_float_noise(v.clone()),
157 None => continue,
158 };
159
160 let mut item = serde_json::Map::new();
162 item.insert("path".to_string(), Value::String(dotted_path));
163 item.insert("value".to_string(), value);
164 result.push(Value::Object(item));
165 }
166
167 Value::Array(result)
168 }
169
170 pub fn get_schema_value_object(&self) -> Value {
177 let mut result = serde_json::Map::new();
178
179 for eval_key in self.value_evaluations.iter() {
180 let clean_key = eval_key.replace('#', "");
181
182 if clean_key.starts_with("/$params")
184 || (clean_key.ends_with("/value")
185 && (clean_key.contains("/rules/") || clean_key.contains("/options/")))
186 {
187 continue;
188 }
189
190 let dotted_path = clean_key
192 .replace("/properties", "")
193 .replace("/value", "")
194 .trim_start_matches('/')
195 .replace('/', ".");
196
197 if dotted_path.is_empty() {
198 continue;
199 }
200
201 let value = match self.evaluated_schema.pointer(&clean_key) {
203 Some(v) => crate::utils::clean_float_noise(v.clone()),
204 None => continue,
205 };
206
207 result.insert(dotted_path, value);
208 }
209
210 Value::Object(result)
211 }
212
213 pub fn get_evaluated_schema_without_params(&mut self, skip_layout: bool) -> Value {
215 let mut schema = self.get_evaluated_schema(skip_layout);
216 if let Value::Object(ref mut map) = schema {
217 map.remove("$params");
218 }
219 schema
220 }
221
222 pub fn get_evaluated_schema_msgpack(&mut self, skip_layout: bool) -> Result<Vec<u8>, String> {
224 let schema = self.get_evaluated_schema(skip_layout);
225 rmp_serde::to_vec(&schema).map_err(|e| format!("MessagePack serialization failed: {}", e))
226 }
227
228 pub fn get_evaluated_schema_by_path(&mut self, path: &str, skip_layout: bool) -> Option<Value> {
230 if !skip_layout {
231 if let Err(e) = self.resolve_layout(false) {
232 eprintln!("Warning: Layout resolution failed in get_evaluated_schema_by_path: {}", e);
233 }
234 }
235 self.get_schema_value_by_path(path)
236 }
237
238 pub fn get_evaluated_schema_by_paths(
240 &mut self,
241 paths: &[String],
242 skip_layout: bool,
243 format: Option<ReturnFormat>,
244 ) -> Value {
245 if !skip_layout {
246 if let Err(e) = self.resolve_layout(false) {
247 eprintln!("Warning: Layout resolution failed in get_evaluated_schema_by_paths: {}", e);
248 }
249 }
250
251 match format.unwrap_or(ReturnFormat::Nested) {
252 ReturnFormat::Nested => {
253 let mut result = Value::Object(serde_json::Map::new());
254 for path in paths {
255 if let Some(val) = self.get_schema_value_by_path(path) {
256 Self::insert_at_path(&mut result, path, val);
258 }
259 }
260 result
261 }
262 ReturnFormat::Flat => {
263 let mut result = serde_json::Map::new();
264 for path in paths {
265 if let Some(val) = self.get_schema_value_by_path(path) {
266 result.insert(path.clone(), val);
267 }
268 }
269 Value::Object(result)
270 }
271 ReturnFormat::Array => {
272 let mut result = Vec::new();
273 for path in paths {
274 if let Some(val) = self.get_schema_value_by_path(path) {
275 result.push(val);
276 } else {
277 result.push(Value::Null);
278 }
279 }
280 Value::Array(result)
281 }
282 }
283 }
284
285 pub fn get_schema_by_path(&self, path: &str) -> Option<Value> {
287 let pointer_path = path_utils::dot_notation_to_schema_pointer(path);
288 self.schema.pointer(&pointer_path.trim_start_matches('#')).cloned()
289 }
290
291 pub fn get_schema_by_paths(
293 &self,
294 paths: &[String],
295 format: Option<ReturnFormat>,
296 ) -> Value {
297 match format.unwrap_or(ReturnFormat::Nested) {
298 ReturnFormat::Nested => {
299 let mut result = Value::Object(serde_json::Map::new());
300 for path in paths {
301 if let Some(val) = self.get_schema_by_path(path) {
302 Self::insert_at_path(&mut result, path, val);
303 }
304 }
305 result
306 }
307 ReturnFormat::Flat => {
308 let mut result = serde_json::Map::new();
309 for path in paths {
310 if let Some(val) = self.get_schema_by_path(path) {
311 result.insert(path.clone(), val);
312 }
313 }
314 Value::Object(result)
315 }
316 ReturnFormat::Array => {
317 let mut result = Vec::new();
318 for path in paths {
319 if let Some(val) = self.get_schema_by_path(path) {
320 result.push(val);
321 } else {
322 result.push(Value::Null);
323 }
324 }
325 Value::Array(result)
326 }
327 }
328 }
329
330 pub(crate) fn insert_at_path(root: &mut Value, path: &str, value: Value) {
332 let parts: Vec<&str> = path.split('.').collect();
333 let mut current = root;
334
335 for (i, part) in parts.iter().enumerate() {
336 if i == parts.len() - 1 {
337 if let Value::Object(map) = current {
339 map.insert(part.to_string(), value);
340 return; }
342 } else {
343 if !current.is_object() {
348 *current = Value::Object(serde_json::Map::new());
349 }
350
351 if let Value::Object(map) = current {
352 if !map.contains_key(*part) {
353 map.insert(part.to_string(), Value::Object(serde_json::Map::new()));
354 }
355 current = map.get_mut(*part).unwrap();
356 }
357 }
358 }
359 }
360
361 pub fn flatten_object(prefix: &str, value: &Value, result: &mut serde_json::Map<String, Value>) {
363 match value {
364 Value::Object(map) => {
365 for (k, v) in map {
366 let new_key = if prefix.is_empty() {
367 k.clone()
368 } else {
369 format!("{}.{}", prefix, k)
370 };
371 Self::flatten_object(&new_key, v, result);
372 }
373 }
374 _ => {
375 result.insert(prefix.to_string(), value.clone());
376 }
377 }
378 }
379
380 pub fn convert_to_format(value: Value, format: ReturnFormat) -> Value {
381 match format {
382 ReturnFormat::Nested => value,
383 ReturnFormat::Flat => {
384 let mut result = serde_json::Map::new();
385 Self::flatten_object("", &value, &mut result);
386 Value::Object(result)
387 }
388 ReturnFormat::Array => {
389 if let Value::Object(map) = value {
393 Value::Array(map.values().cloned().collect())
394 } else if let Value::Array(arr) = value {
395 Value::Array(arr)
396 } else {
397 Value::Array(vec![value])
398 }
399 }
400 }
401 }
402}