1use serde_json::{Map, Value};
2
3use crate::spec::form::FormSpec;
4
5pub type VisibilityMap = std::collections::BTreeMap<String, bool>;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum VisibilityMode {
9 Visible,
10 Hidden,
11 Error,
12}
13
14pub fn resolve_visibility(spec: &FormSpec, answers: &Value, mode: VisibilityMode) -> VisibilityMap {
15 let mut map = VisibilityMap::new();
16 let mut ctx_map = Map::new();
17 ctx_map.insert("answers".into(), answers.clone());
18 let ctx = Value::Object(ctx_map);
19
20 for question in &spec.questions {
21 let visible = if let Some(expr) = &question.visible_if {
22 match expr.evaluate(&ctx) {
23 Some(val) => val,
24 None => match mode {
25 VisibilityMode::Visible => true,
26 VisibilityMode::Hidden => false,
27 VisibilityMode::Error => true,
28 },
29 }
30 } else {
31 true
32 };
33 map.insert(question.id.clone(), visible);
34 }
35
36 map
37}