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