Skip to main content

rust_store_core/pipeline/
ast.rs

1//! AST 数据定义与 JSON 互转
2
3use std::collections::HashMap;
4
5use serde_json::{Map, Value};
6
7/// 关系节点。`relations` 用 `Vec` 保序:pipeline 阶段数组顺序依赖 GQL 中的出现顺序。
8#[derive(Debug, Clone)]
9pub struct RelAst {
10    pub fields: Vec<String>,
11    pub relations: Vec<(String, RelAst)>,
12    pub params: HashMap<String, String>,
13}
14
15impl RelAst {
16    pub fn to_value(&self) -> Value {
17        Value::Object(Map::from_iter([
18            (
19                "fields".to_string(),
20                Value::Array(self.fields.iter().cloned().map(Value::String).collect()),
21            ),
22            ("relations".to_string(), relations_to_value(&self.relations)),
23            (
24                "params".to_string(),
25                Value::Object(
26                    self.params
27                        .iter()
28                        .map(|(k, v)| (k.clone(), Value::String(v.clone())))
29                        .collect(),
30                ),
31            ),
32        ]))
33    }
34
35    /// 从 [`to_value`] 产出的 JSON 重建(供 finalize_query 从 plan.postprocess 还原 AST)
36    pub fn from_value(v: &Value) -> Result<RelAst, String> {
37        let obj = v
38            .as_object()
39            .ok_or_else(|| "RelAst 必须是对象".to_string())?;
40        let fields = match obj.get("fields") {
41            Some(Value::Array(arr)) => arr
42                .iter()
43                .map(|f| f.as_str().unwrap_or_default().to_string())
44                .collect(),
45            _ => Vec::new(),
46        };
47        let mut relations = Vec::new();
48        if let Some(Value::Object(rm)) = obj.get("relations") {
49            for (k, rv) in rm {
50                relations.push((k.clone(), RelAst::from_value(rv)?));
51            }
52        }
53        let mut params = HashMap::new();
54        if let Some(Value::Object(pm)) = obj.get("params") {
55            for (k, pv) in pm {
56                if let Some(s) = pv.as_str() {
57                    params.insert(k.clone(), s.to_string());
58                }
59            }
60        }
61        Ok(RelAst {
62            fields,
63            relations,
64            params,
65        })
66    }
67}
68
69#[derive(Debug, Clone)]
70pub struct Ast {
71    pub model: String,
72    pub params: HashMap<String, String>,
73    pub fields: Vec<String>,
74    pub relations: Vec<(String, RelAst)>,
75}
76
77impl Ast {
78    pub fn to_value(&self) -> Value {
79        Value::Object(Map::from_iter([
80            ("model".to_string(), Value::String(self.model.clone())),
81            (
82                "params".to_string(),
83                Value::Object(
84                    self.params
85                        .iter()
86                        .map(|(k, v)| (k.clone(), Value::String(v.clone())))
87                        .collect(),
88                ),
89            ),
90            (
91                "fields".to_string(),
92                Value::Array(self.fields.iter().cloned().map(Value::String).collect()),
93            ),
94            ("relations".to_string(), relations_to_value(&self.relations)),
95        ]))
96    }
97
98    /// 从 [`to_value`] 产出的 JSON 重建(供 finalize_query 从 plan.postprocess 还原 AST)
99    pub fn from_value(v: &Value) -> Result<Ast, String> {
100        let obj = v.as_object().ok_or_else(|| "Ast 必须是对象".to_string())?;
101        let model = obj
102            .get("model")
103            .and_then(|m| m.as_str())
104            .unwrap_or_default()
105            .to_string();
106        let mut params = HashMap::new();
107        if let Some(Value::Object(pm)) = obj.get("params") {
108            for (k, pv) in pm {
109                if let Some(s) = pv.as_str() {
110                    params.insert(k.clone(), s.to_string());
111                }
112            }
113        }
114        let fields = match obj.get("fields") {
115            Some(Value::Array(arr)) => arr
116                .iter()
117                .map(|f| f.as_str().unwrap_or_default().to_string())
118                .collect(),
119            _ => Vec::new(),
120        };
121        let mut relations = Vec::new();
122        if let Some(Value::Object(rm)) = obj.get("relations") {
123            for (k, rv) in rm {
124                relations.push((k.clone(), RelAst::from_value(rv)?));
125            }
126        }
127        Ok(Ast {
128            model,
129            params,
130            fields,
131            relations,
132        })
133    }
134}
135
136fn relations_to_value(relations: &[(String, RelAst)]) -> Value {
137    Value::Object(
138        relations
139            .iter()
140            .map(|(k, v)| (k.clone(), v.to_value()))
141            .collect(),
142    )
143}