Skip to main content

json_eval_rs/jsoneval/
subform_methods.rs

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