use crate::{DependentItem, LogicId, RLogic, RLogicConfig, TableMetadata};
use indexmap::{IndexMap, IndexSet};
use serde_json::Value;
use std::sync::Arc;
pub struct ParsedSchema {
pub schema: Arc<Value>,
pub engine: Arc<RLogic>,
pub evaluations: Arc<IndexMap<String, LogicId>>,
pub tables: Arc<IndexMap<String, Value>>,
pub table_metadata: Arc<IndexMap<String, TableMetadata>>,
pub dependencies: Arc<IndexMap<String, IndexSet<String>>>,
pub sorted_evaluations: Arc<Vec<Vec<String>>>,
pub dependents_evaluations: Arc<IndexMap<String, Vec<DependentItem>>>,
pub rules_evaluations: Arc<Vec<String>>,
pub fields_with_rules: Arc<Vec<String>>,
pub others_evaluations: Arc<Vec<String>>,
pub value_evaluations: Arc<Vec<String>>,
pub layout_paths: Arc<Vec<String>>,
pub options_templates: Arc<Vec<(String, String, String)>>,
pub subforms: IndexMap<String, Arc<ParsedSchema>>,
pub reffed_by: Arc<IndexMap<String, Vec<String>>>,
pub dep_formula_triggers: Arc<IndexMap<String, Vec<(String, usize)>>>,
pub conditional_hidden_fields: Arc<Vec<String>>,
pub conditional_readonly_fields: Arc<Vec<String>>,
pub static_arrays: Arc<IndexMap<String, Arc<Value>>>,
}
impl ParsedSchema {
pub fn parse(schema: &str) -> Result<Self, String> {
let schema_val: Value = serde_json::from_str(schema)
.map_err(|e| format!("Failed to parse schema JSON: {}", e))?;
Self::parse_value(schema_val)
}
pub fn parse_value(mut schema_val: Value) -> Result<Self, String> {
let engine_config = RLogicConfig::default();
let static_arrays = if let Some(params) = schema_val
.get_mut("$params")
.and_then(|v| v.as_object_mut())
{
crate::jsoneval::static_arrays::extract_from_params(params)
} else {
IndexMap::new()
};
let static_arrays = Arc::new(static_arrays);
let mut engine = RLogic::with_config(engine_config);
engine.set_static_arrays(Arc::clone(&static_arrays));
let mut parsed = Self {
schema: Arc::new(schema_val),
engine: Arc::new(engine),
evaluations: Arc::new(IndexMap::new()),
tables: Arc::new(IndexMap::new()),
table_metadata: Arc::new(IndexMap::new()),
dependencies: Arc::new(IndexMap::new()),
sorted_evaluations: Arc::new(Vec::new()),
dependents_evaluations: Arc::new(IndexMap::new()),
rules_evaluations: Arc::new(Vec::new()),
fields_with_rules: Arc::new(Vec::new()),
others_evaluations: Arc::new(Vec::new()),
value_evaluations: Arc::new(Vec::new()),
layout_paths: Arc::new(Vec::new()),
options_templates: Arc::new(Vec::new()),
subforms: IndexMap::new(),
reffed_by: Arc::new(IndexMap::new()),
dep_formula_triggers: Arc::new(IndexMap::new()),
conditional_hidden_fields: Arc::new(Vec::new()),
conditional_readonly_fields: Arc::new(Vec::new()),
static_arrays,
};
crate::parse_schema::parsed::parse_schema_into(&mut parsed)?;
Ok(parsed)
}
pub fn parse_msgpack(schema_msgpack: &[u8]) -> Result<Self, String> {
let schema_val: Value = rmp_serde::from_slice(schema_msgpack)
.map_err(|e| format!("Failed to deserialize MessagePack schema: {}", e))?;
Self::parse_value(schema_val).map_err(|e| format!("Failed to parse schema: {}", e))
}
pub fn schema(&self) -> &Value {
&*self.schema
}
}