polyspec_crudui_generator/
outline.rs1use serde_json::{Map, Value};
4
5fn children(node: &Value) -> &[Value] {
7 node.get("children")
8 .and_then(Value::as_array)
9 .map_or(&[], Vec::as_slice)
10}
11
12fn rows(nodes: &[Value]) -> Vec<Value> {
14 nodes
15 .iter()
16 .flat_map(|node| {
17 if node["kind"] == "collection" {
18 let path = node["path"].as_str().unwrap_or("");
19 children(node).iter().map(|row| entry(path, row)).collect()
20 } else {
21 rows(children(node))
22 }
23 })
24 .collect()
25}
26
27fn entry(path: &str, row: &Value) -> Value {
29 let mut entry = Map::new();
30 entry.insert("path".into(), path.into());
31 entry.insert("key".into(), row["key"].as_str().unwrap_or("").into());
32 for name in ["number", "title"] {
33 if let Some(text) = row["header"].get(name).filter(|text| !text.is_null()) {
34 entry.insert(name.into(), text.clone());
35 }
36 }
37 if row["controls"]["placement"] == "outline" {
38 entry.insert("controls".into(), row["controls"].clone());
39 }
40 entry.insert("rows".into(), Value::Array(rows(children(row))));
41 Value::Object(entry)
42}
43
44pub fn build_outline(nodes: &[Value]) -> Vec<Value> {
46 rows(nodes)
47}