rust_store_core/dialect/
overlay.rs1use serde_json::{Map, Value};
4
5pub fn merge_schema(base: &Value, overlay: &Value) -> Result<Value, String> {
10 let base_arr = base.as_array().cloned().unwrap_or_default();
11 let overlay_arr = overlay.as_array().cloned().unwrap_or_default();
12
13 let mut out: Vec<Value> = Vec::new();
15 for b in &base_arr {
16 let name = b
17 .get("name")
18 .and_then(|v| v.as_str())
19 .unwrap_or("")
20 .to_string();
21 let over = overlay_arr
22 .iter()
23 .find(|o| o.get("name").and_then(|v| v.as_str()) == Some(name.as_str()));
24 out.push(match over {
25 Some(o) => merge_one(b, o)?,
26 None => b.clone(),
27 });
28 }
29 for o in &overlay_arr {
31 let name = o
32 .get("name")
33 .and_then(|v| v.as_str())
34 .unwrap_or("")
35 .to_string();
36 let exists = base_arr
37 .iter()
38 .any(|b| b.get("name").and_then(|v| v.as_str()) == Some(name.as_str()));
39 if !exists {
40 out.push(o.clone());
41 }
42 }
43 Ok(Value::Array(out))
44}
45
46fn merge_one(base: &Value, overlay: &Value) -> Result<Value, String> {
48 let mut out = base.clone();
49 let b = base.as_object().cloned().unwrap_or_default();
50 let b_fields = b
51 .get("fields")
52 .and_then(|f| f.as_object())
53 .cloned()
54 .unwrap_or_default();
55 let b_rels = b
56 .get("relations")
57 .and_then(|f| f.as_object())
58 .cloned()
59 .unwrap_or_default();
60
61 if let Some(o) = overlay.as_object() {
62 let mut all_fields = b_fields;
64 if let Some(of) = o.get("fields").and_then(|f| f.as_object()) {
65 for (k, v) in of {
66 all_fields.insert(k.clone(), v.clone());
67 }
68 }
69 if let Some(rel_obj) = out.get_mut("fields") {
70 *rel_obj = Value::Object(all_fields);
71 }
72
73 let mut all_rels = b_rels;
75 if let Some(or) = o.get("relations").and_then(|f| f.as_object()) {
76 for (k, v) in or {
77 all_rels.insert(k.clone(), v.clone());
78 }
79 }
80 if let Some(rel_obj) = out.get_mut("relations") {
81 *rel_obj = Value::Object(all_rels);
82 }
83
84 for key in ["read", "write", "idPrefix", "collection"] {
86 if let Some(v) = o.get(key) {
87 if let Some(target) = out.get_mut(key) {
88 *target = v.clone();
89 } else {
90 out.as_object_mut()
91 .map(|m| m.insert(key.to_string(), v.clone()));
92 }
93 }
94 }
95
96 if let Some(c) = o.get("computes") {
98 out.as_object_mut()
99 .map(|m| m.insert("computes".to_string(), c.clone()));
100 }
101 if let Some(i) = o.get("indexes") {
102 out.as_object_mut()
103 .map(|m| m.insert("indexes".to_string(), i.clone()));
104 }
105 }
106 Ok(out)
107}
108
109pub fn merge_one_schema_json(base: &Value, overlay: &Value) -> Result<Value, String> {
111 if base.get("name").is_some() && base.get("fields").is_some() {
112 merge_one(base, overlay)
113 } else {
114 Err("base 不是单个 schema def".to_string())
115 }
116}
117
118#[allow(dead_code)]
119fn _map_helper() -> Map<String, Value> {
120 Map::new()
121}