polyspec_crudui_validator/validate/
visibility.rs1use serde_json::Value;
5
6use super::rules::is_condition_expression;
7use super::validator::has_ternary_regex;
8use crate::expr::{condition_map, Evaluator, Expression, Node};
9
10pub fn show(value: Option<&Value>, data: &Value, path: &[String], row_keys: &[usize]) -> bool {
18 let resolved = match value {
19 None => return true,
20 Some(Value::Object(map)) => {
21 let entries: Vec<(String, Value)> =
22 map.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
23 condition_map::resolve(&entries, data, path, row_keys).unwrap_or(Value::Null)
24 }
25 Some(Value::String(expression)) => match Expression::parse(expression) {
26 Ok(node @ Node::Ternary { .. }) => {
27 Evaluator::new(data, path, row_keys).evaluate_value(&node)
28 }
29 Ok(node) if is_condition_expression(expression) && !has_ternary_regex(expression) => {
30 Evaluator::new(data, path, row_keys).evaluate_value(&node)
31 }
32 _ => return true,
33 },
34 Some(literal) => literal.clone(),
35 };
36 resolved != Value::Bool(false)
37}
38
39pub fn is_visible(field: &Value, data: &Value, path: &[String], row_keys: &[usize]) -> bool {
42 match field.get("design") {
43 Some(Value::Object(design)) => show(design.get("show"), data, path, row_keys),
44 _ => true,
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use serde_json::json;
52
53 #[test]
54 fn show_values() {
55 let data = json!({ "on": 1, "rows": { "r": { "kind": "a" } } });
56 let path = |p: &str| p.split('.').map(String::from).collect::<Vec<_>>();
57 assert!(show(None, &data, &path("x"), &[]));
58 assert!(show(Some(&json!(null)), &data, &path("x"), &[]));
59 assert!(show(
60 Some(&json!("not an (expression")),
61 &data,
62 &path("x"),
63 &[]
64 ));
65 assert!(show(Some(&json!(true)), &data, &path("x"), &[]));
66 assert!(!show(Some(&json!(false)), &data, &path("x"), &[]));
67 assert!(show(Some(&json!(".on")), &data, &path("x"), &[]));
68 assert!(!show(Some(&json!(".off")), &data, &path("x"), &[]));
69 assert!(show(
70 Some(&json!(".kind == 'a'")),
71 &data,
72 &path("rows.r.note"),
73 &[]
74 ));
75 assert!(!show(
76 Some(&json!({ ".on": false, "true": true })),
77 &data,
78 &path("x"),
79 &[]
80 ));
81 assert!(show(
82 Some(&json!({ ".off": false, "true": true })),
83 &data,
84 &path("x"),
85 &[]
86 ));
87 assert!(show(
88 Some(&json!({ ".off": false })),
89 &data,
90 &path("x"),
91 &[]
92 ));
93 assert!(show(Some(&json!({ ".on": null })), &data, &path("x"), &[]));
94 assert!(is_visible(
95 &json!({ "design": false }),
96 &data,
97 &path("x"),
98 &[]
99 ));
100 assert!(!is_visible(
101 &json!({ "design": { "show": false } }),
102 &data,
103 &path("x"),
104 &[]
105 ));
106 }
107}