#![expect(
clippy::disallowed_types,
reason = "canonical JSON / Simplified Formats operate on the wire value by definition \
(ITS-JSON; ITS-REST Simplified Formats) — serde_json::Value IS the subject matter \
(#1694)"
)]
use serde_json::{Map, Value};
use crate::flat::build;
use crate::flat::error::FlatError;
use crate::flat::flatten;
use crate::flat::sim::flat;
use crate::flat::sim::structured;
use crate::flat::webtemplate::model::WebTemplate;
pub fn composition_from_flat(
doc: &Map<String, Value>,
wt: &WebTemplate,
now: &str,
) -> Result<Value, FlatError> {
let tree = flat::parse_flat(doc)?;
build::build_composition(&tree, wt, now)
}
pub fn submitted_composition_from_flat(
doc: &Map<String, Value>,
wt: &WebTemplate,
now: &str,
) -> Result<Value, FlatError> {
let tree = flat::parse_flat(doc)?;
let built = build::build_composition(&tree, wt, now)?;
require_input_valid(doc, &tree, wt)?;
Ok(built)
}
fn require_input_valid(
doc: &Map<String, Value>,
tree: &crate::flat::sim::SimDocument,
wt: &WebTemplate,
) -> Result<(), FlatError> {
if let Some(m) = crate::flat::validation::validate_context(tree).first() {
let field = if m.path.ends_with("territory") {
"territory"
} else {
"language"
};
return Err(FlatError::MissingContext(field));
}
if let Some((path, code)) = crate::flat::validation::unresolvable_coded_leaves(doc, wt)
.into_iter()
.next()
{
return Err(FlatError::CodeNotInValueSet { path, code });
}
Ok(())
}
pub fn composition_to_flat(
composition: &Value,
wt: &WebTemplate,
) -> Result<Map<String, Value>, FlatError> {
let tree = flatten::flatten_composition(composition, wt)?;
Ok(flat::emit_flat(&tree))
}
pub fn composition_from_structured(
doc: &Value,
wt: &WebTemplate,
now: &str,
) -> Result<Value, FlatError> {
let tree = structured::parse_structured(doc)?;
build::build_composition(&tree, wt, now)
}
pub fn submitted_composition_from_structured(
doc: &Value,
wt: &WebTemplate,
now: &str,
) -> Result<Value, FlatError> {
let tree = structured::parse_structured(doc)?;
let built = build::build_composition(&tree, wt, now)?;
let flat_view = flat::emit_flat(&tree);
require_input_valid(&flat_view, &tree, wt)?;
Ok(built)
}
pub fn composition_to_structured(
composition: &Value,
wt: &WebTemplate,
) -> Result<Value, FlatError> {
let tree = flatten::flatten_composition(composition, wt)?;
Ok(structured::emit_structured(&tree))
}
pub fn party_from_flat(
doc: &Map<String, Value>,
wt: &WebTemplate,
options: &build::BuildOptions<'_>,
) -> Result<Value, FlatError> {
let tree = flat::parse_flat(doc)?;
build::build_party(&tree, wt, options)
}
pub fn party_from_structured(
doc: &Value,
wt: &WebTemplate,
options: &build::BuildOptions<'_>,
) -> Result<Value, FlatError> {
let tree = structured::parse_structured(doc)?;
build::build_party(&tree, wt, options)
}
pub fn flat_to_structured(doc: &Map<String, Value>) -> Result<Value, FlatError> {
Ok(structured::emit_structured(&flat::parse_flat(doc)?))
}
pub fn structured_to_flat(doc: &Value) -> Result<Map<String, Value>, FlatError> {
Ok(flat::emit_flat(&structured::parse_structured(doc)?))
}