regast_syntax/print/
json.rs1use std::convert::Infallible;
2
3use serde_json::{Value, json};
4
5use super::{JsonShape, kind_name, rep_name};
6use crate::{AstKind, Cursor, Flow, GroupKind, Pattern, Visitor, visit};
7
8impl Pattern {
9 #[must_use]
10 pub fn to_json(&self, shape: JsonShape) -> Value {
11 match shape {
12 JsonShape::Tree => json!({
13 "schema_version": 1,
14 "pattern": self.source(),
15 "shape": "tree",
16 "root": run_visitor(self, TreeJson::default()),
17 }),
18 JsonShape::Arena => json!({
19 "schema_version": 1,
20 "pattern": self.source(),
21 "shape": "arena",
22 "root": self.root_id().0,
23 "nodes": run_visitor(self, ArenaJson::default()),
24 }),
25 }
26 }
27}
28
29fn run_visitor<V>(pattern: &Pattern, visitor: V) -> V::Output
30where
31 V: Visitor<Err = Infallible>,
32{
33 match visit(pattern, visitor) {
34 Ok(output) => output,
35 Err(error) => match error {},
36 }
37}
38
39#[derive(Default)]
40struct TreeJson {
41 stack: Vec<Value>,
42 root: Option<Value>,
43}
44
45impl Visitor for TreeJson {
46 type Output = Value;
47 type Err = Infallible;
48
49 fn enter(&mut self, node: Cursor<'_>) -> Result<Flow, Self::Err> {
50 self.stack.push(node_json(node));
51 Ok(Flow::Continue)
52 }
53
54 fn leave(&mut self, _node: Cursor<'_>) -> Result<(), Self::Err> {
55 let completed = self.stack.pop().expect("enter precedes leave");
56 if let Some(parent) = self.stack.last_mut() {
57 let object = parent.as_object_mut().expect("node JSON is an object");
58 object
59 .entry("children")
60 .or_insert_with(|| Value::Array(Vec::new()))
61 .as_array_mut()
62 .expect("children is an array")
63 .push(completed);
64 } else {
65 self.root = Some(completed);
66 }
67 Ok(())
68 }
69
70 fn finish(self) -> Result<Self::Output, Self::Err> {
71 Ok(self.root.expect("pattern always has a root"))
72 }
73}
74
75#[derive(Default)]
76struct ArenaJson {
77 nodes: Vec<Value>,
78}
79
80impl Visitor for ArenaJson {
81 type Output = Vec<Value>;
82 type Err = Infallible;
83
84 fn enter(&mut self, node: Cursor<'_>) -> Result<Flow, Self::Err> {
85 self.nodes.push(json!({
86 "id": node.id().0,
87 "span": [node.span().start, node.span().end],
88 "parent": node.parent().map(|parent| parent.id().0),
89 "kind": kind_name(node.kind()),
90 "children": node.children().map(|child| child.id().0).collect::<Vec<_>>(),
91 "text": node.text(),
92 }));
93 Ok(Flow::Continue)
94 }
95
96 fn finish(mut self) -> Result<Self::Output, Self::Err> {
97 self.nodes.sort_by_key(|node| node["id"].as_u64());
98 Ok(self.nodes)
99 }
100}
101
102fn node_json(cursor: Cursor<'_>) -> Value {
103 let mut value = json!({
104 "id": cursor.id().0,
105 "kind": kind_name(cursor.kind()),
106 "span": [cursor.span().start, cursor.span().end],
107 "text": cursor.text(),
108 });
109 let object = value.as_object_mut().expect("object literal");
110 match cursor.kind() {
111 AstKind::Literal { c, escaped } => {
112 object.insert("c".into(), json!(c));
113 object.insert("escaped".into(), json!(escaped));
114 }
115 AstKind::Class { negated, set, .. } => {
116 object.insert("negated".into(), json!(negated));
117 object.insert("set".into(), json!(set));
118 }
119 AstKind::Group { kind, .. } => add_group_fields(object, kind),
120 AstKind::Repeat { kind, greedy, .. } => {
121 object.insert("rep".into(), json!(rep_name(*kind)));
122 object.insert("greedy".into(), json!(greedy));
123 }
124 AstKind::Anchor { kind } => {
125 object.insert("anchor".into(), json!(kind));
126 }
127 AstKind::Empty | AstKind::Dot | AstKind::Alt { .. } | AstKind::Concat { .. } => {}
128 }
129 value
130}
131
132fn add_group_fields(object: &mut serde_json::Map<String, Value>, kind: &GroupKind) {
133 match kind {
134 GroupKind::Capture { index, name } => {
135 object.insert("capture".into(), json!(index));
136 object.insert("name".into(), json!(name));
137 }
138 GroupKind::NonCapture => {
139 object.insert("capture".into(), Value::Null);
140 }
141 }
142}