json_eval_rs/jsoneval/
subform_methods.rs

1// Subform methods for isolated array field evaluation
2
3use crate::JSONEval;
4use crate::ReturnFormat;
5use serde_json::Value;
6
7impl JSONEval {
8    /// Evaluate a subform with data
9    /// Evaluate a subform with data and optional selective paths
10    pub fn evaluate_subform(
11        &mut self,
12        subform_path: &str,
13        data: &str,
14        context: Option<&str>,
15        paths: Option<&[String]>,
16    ) -> Result<(), String> {
17        let subform = self
18            .subforms
19            .get_mut(subform_path)
20            .ok_or_else(|| format!("Subform not found: {}", subform_path))?;
21
22        subform.evaluate(data, context, paths)
23    }
24
25    /// Validate subform data against its schema rules
26    pub fn validate_subform(
27        &mut self,
28        subform_path: &str,
29        data: &str,
30        context: Option<&str>,
31        paths: Option<&[String]>,
32    ) -> Result<crate::ValidationResult, String> {
33        let subform = self
34            .subforms
35            .get_mut(subform_path)
36            .ok_or_else(|| format!("Subform not found: {}", subform_path))?;
37
38        subform.validate(data, context, paths)
39    }
40
41    /// Evaluate dependents in subform when a field changes
42    pub fn evaluate_dependents_subform(
43        &mut self,
44        subform_path: &str,
45        changed_paths: &[String],
46        data: Option<&str>,
47        context: Option<&str>,
48        re_evaluate: bool,
49    ) -> Result<Value, String> {
50        let subform = self
51            .subforms
52            .get_mut(subform_path)
53            .ok_or_else(|| format!("Subform not found: {}", subform_path))?;
54
55        subform.evaluate_dependents(changed_paths, data, context, re_evaluate)
56    }
57
58    /// Resolve layout for subform
59    pub fn resolve_layout_subform(
60        &mut self,
61        subform_path: &str,
62        evaluate: bool,
63    ) -> Result<(), String> {
64        let subform = self
65            .subforms
66            .get_mut(subform_path)
67            .ok_or_else(|| format!("Subform not found: {}", subform_path))?;
68
69        let _ = subform.resolve_layout(evaluate);
70        Ok(())
71    }
72
73    /// Get evaluated schema from subform
74    pub fn get_evaluated_schema_subform(
75        &mut self,
76        subform_path: &str,
77        resolve_layout: bool,
78    ) -> Value {
79        if let Some(subform) = self.subforms.get_mut(subform_path) {
80            subform.get_evaluated_schema(resolve_layout)
81        } else {
82            Value::Null
83        }
84    }
85
86    /// Get schema value from subform (all .value fields)
87    pub fn get_schema_value_subform(&mut self, subform_path: &str) -> Value {
88        if let Some(subform) = self.subforms.get_mut(subform_path) {
89            subform.get_schema_value()
90        } else {
91            Value::Null
92        }
93    }
94
95    /// Get evaluated schema without $params from subform
96    pub fn get_evaluated_schema_without_params_subform(
97        &mut self,
98        subform_path: &str,
99        resolve_layout: bool,
100    ) -> Value {
101        if let Some(subform) = self.subforms.get_mut(subform_path) {
102            subform.get_evaluated_schema_without_params(resolve_layout)
103        } else {
104            Value::Null
105        }
106    }
107
108    /// Get evaluated schema by specific path from subform
109    pub fn get_evaluated_schema_by_path_subform(
110        &mut self,
111        subform_path: &str,
112        schema_path: &str,
113        skip_layout: bool,
114    ) -> Option<Value> {
115        if let Some(subform) = self.subforms.get_mut(subform_path) {
116            Some(subform.get_evaluated_schema_by_paths(&[schema_path.to_string()], skip_layout, Some(ReturnFormat::Nested)))
117        } else {
118            None
119        }
120    }
121
122    /// Get evaluated schema by multiple paths from subform
123    pub fn get_evaluated_schema_by_paths_subform(
124        &mut self,
125        subform_path: &str,
126        schema_paths: &[String],
127        skip_layout: bool,
128        format: Option<crate::ReturnFormat>,
129    ) -> Value {
130        if let Some(subform) = self.subforms.get_mut(subform_path) {
131            subform.get_evaluated_schema_by_paths(schema_paths, skip_layout, Some(format.unwrap_or(ReturnFormat::Flat)))
132        } else {
133            match format.unwrap_or_default() {
134                crate::ReturnFormat::Array => Value::Array(vec![]),
135                _ => Value::Object(serde_json::Map::new()),
136            }
137        }
138    }
139
140    /// Get schema by specific path from subform
141    pub fn get_schema_by_path_subform(
142        &self,
143        subform_path: &str,
144        schema_path: &str,
145    ) -> Option<Value> {
146        if let Some(subform) = self.subforms.get(subform_path) {
147            subform.get_schema_by_path(schema_path)
148        } else {
149            None
150        }
151    }
152
153    /// Get schema by multiple paths from subform
154    pub fn get_schema_by_paths_subform(
155        &self,
156        subform_path: &str,
157        schema_paths: &[String],
158        format: Option<crate::ReturnFormat>,
159    ) -> Value {
160        if let Some(subform) = self.subforms.get(subform_path) {
161            subform.get_schema_by_paths(schema_paths, Some(format.unwrap_or(ReturnFormat::Flat)))
162        } else {
163            match format.unwrap_or_default() {
164                crate::ReturnFormat::Array => Value::Array(vec![]),
165                _ => Value::Object(serde_json::Map::new()),
166            }
167        }
168    }
169
170    /// Get list of available subform paths
171    pub fn get_subform_paths(&self) -> Vec<String> {
172        self.subforms.keys().cloned().collect()
173    }
174
175    /// Check if a subform exists at the given path
176    pub fn has_subform(&self, subform_path: &str) -> bool {
177        self.subforms.contains_key(subform_path)
178    }
179}