snix_eval/
pretty_ast.rs

1//! Pretty-printed format for the rnix AST representation.
2//!
3//! The AST is serialised into a JSON structure that can then be
4//! printed in either minimised or well-formatted style.
5
6use rnix::ast::{self, AstToken, HasEntry};
7use serde::{ser::SerializeMap, Serialize, Serializer};
8
9pub fn pretty_print_expr(expr: &ast::Expr) -> String {
10    serde_json::ser::to_string_pretty(&SerializeAST(expr))
11        .expect("serializing AST should always succeed")
12}
13
14#[repr(transparent)]
15struct SerializeAST<S>(S);
16
17impl Serialize for SerializeAST<&ast::Apply> {
18    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
19        let mut map = serializer.serialize_map(Some(3))?;
20        map.serialize_entry("kind", "apply")?;
21        map.serialize_entry("fn", &SerializeAST(&self.0.lambda().unwrap()))?;
22        map.serialize_entry("arg", &SerializeAST(&self.0.argument().unwrap()))?;
23        map.end()
24    }
25}
26
27impl Serialize for SerializeAST<&ast::Assert> {
28    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
29        let mut map = serializer.serialize_map(Some(3))?;
30        map.serialize_entry("kind", "assert")?;
31        map.serialize_entry("condition", &SerializeAST(&self.0.condition().unwrap()))?;
32        map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
33        map.end()
34    }
35}
36
37impl Serialize for SerializeAST<&ast::Error> {
38    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
39        let mut map = serializer.serialize_map(Some(2))?;
40        map.serialize_entry("kind", "error")?;
41        map.serialize_entry("node", &self.0.to_string())?;
42        map.end()
43    }
44}
45
46impl Serialize for SerializeAST<&ast::IfElse> {
47    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
48        let mut map = serializer.serialize_map(Some(4))?;
49        map.serialize_entry("kind", "if_else")?;
50        map.serialize_entry("condition", &SerializeAST(&self.0.condition().unwrap()))?;
51        map.serialize_entry("then_body", &SerializeAST(&self.0.body().unwrap()))?;
52        map.serialize_entry("else_body", &SerializeAST(&self.0.else_body().unwrap()))?;
53        map.end()
54    }
55}
56
57impl Serialize for SerializeAST<&ast::Select> {
58    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
59        let size = match self.0.default_expr() {
60            Some(_) => 4,
61            None => 3,
62        };
63
64        let mut map = serializer.serialize_map(Some(size))?;
65        map.serialize_entry("kind", "select")?;
66        map.serialize_entry("set", &SerializeAST(&self.0.expr().unwrap()))?;
67        map.serialize_entry("path", &SerializeAST(self.0.attrpath().unwrap()))?;
68
69        if let Some(default) = self.0.default_expr() {
70            map.serialize_entry("default", &SerializeAST(&default))?;
71        }
72
73        map.end()
74    }
75}
76
77impl Serialize for SerializeAST<ast::InterpolPart<String>> {
78    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
79        match &self.0 {
80            ast::InterpolPart::Literal(s) => Serialize::serialize(s, serializer),
81            ast::InterpolPart::Interpolation(node) => {
82                Serialize::serialize(&SerializeAST(&node.expr().unwrap()), serializer)
83            }
84        }
85    }
86}
87
88impl Serialize for SerializeAST<&ast::Str> {
89    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
90        let mut map = serializer.serialize_map(Some(2))?;
91        map.serialize_entry("kind", "string")?;
92
93        map.serialize_entry(
94            "parts",
95            &self
96                .0
97                .normalized_parts()
98                .into_iter()
99                .map(SerializeAST)
100                .collect::<Vec<_>>(),
101        )?;
102
103        map.end()
104    }
105}
106
107impl Serialize for SerializeAST<ast::InterpolPart<ast::PathContent>> {
108    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
109        match &self.0 {
110            ast::InterpolPart::Literal(p) => Serialize::serialize(p.syntax().text(), serializer),
111            ast::InterpolPart::Interpolation(node) => {
112                Serialize::serialize(&SerializeAST(&node.expr().unwrap()), serializer)
113            }
114        }
115    }
116}
117
118impl Serialize for SerializeAST<&ast::Path> {
119    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
120        let mut map = serializer.serialize_map(Some(2))?;
121        map.serialize_entry("kind", "path")?;
122
123        map.serialize_entry(
124            "parts",
125            &self.0.parts().map(SerializeAST).collect::<Vec<_>>(),
126        )?;
127
128        map.end()
129    }
130}
131
132impl Serialize for SerializeAST<&ast::Literal> {
133    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
134        let mut map = serializer.serialize_map(Some(2))?;
135        map.serialize_entry("kind", "literal")?;
136
137        match self.0.kind() {
138            ast::LiteralKind::Float(val) => map.serialize_entry("float", &val.value().unwrap()),
139            ast::LiteralKind::Integer(val) => map.serialize_entry("int", &val.value().unwrap()),
140            ast::LiteralKind::Uri(val) => map.serialize_entry("uri", val.syntax().text()),
141        }?;
142
143        map.end()
144    }
145}
146
147impl Serialize for SerializeAST<ast::PatEntry> {
148    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
149        let mut map = serializer.serialize_map(None)?;
150        map.serialize_entry("ident", &SerializeAST(&self.0.ident().unwrap()))?;
151
152        if let Some(default) = self.0.default() {
153            map.serialize_entry("default", &SerializeAST(&default))?;
154        }
155
156        map.end()
157    }
158}
159
160impl Serialize for SerializeAST<ast::Param> {
161    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
162        match &self.0 {
163            ast::Param::Pattern(pat) => {
164                let mut map = serializer.serialize_map(None)?;
165                map.serialize_entry("kind", "formals")?;
166
167                map.serialize_entry(
168                    "entries",
169                    &pat.pat_entries().map(SerializeAST).collect::<Vec<_>>(),
170                )?;
171
172                if let Some(bind) = pat.pat_bind() {
173                    map.serialize_entry("bind", &SerializeAST(&bind.ident().unwrap()))?;
174                }
175
176                map.serialize_entry("ellipsis", &pat.ellipsis_token().is_some())?;
177
178                map.end()
179            }
180
181            ast::Param::IdentParam(node) => {
182                Serialize::serialize(&SerializeAST(&node.ident().unwrap()), serializer)
183            }
184        }
185    }
186}
187
188impl Serialize for SerializeAST<&ast::Lambda> {
189    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
190        let mut map = serializer.serialize_map(Some(3))?;
191        map.serialize_entry("kind", "lambda")?;
192        map.serialize_entry("param", &SerializeAST(self.0.param().unwrap()))?;
193        map.serialize_entry("body", &SerializeAST(self.0.body().unwrap()))?;
194        map.end()
195    }
196}
197
198impl Serialize for SerializeAST<&ast::LegacyLet> {
199    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
200        let mut map = serializer.serialize_map(Some(3))?;
201        map.serialize_entry("kind", "legacy_let")?;
202
203        map.serialize_entry(
204            "entries",
205            &self
206                .0
207                .attrpath_values()
208                .map(SerializeAST)
209                .collect::<Vec<_>>(),
210        )?;
211
212        map.serialize_entry(
213            "inherits",
214            &self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
215        )?;
216
217        map.end()
218    }
219}
220
221impl Serialize for SerializeAST<&ast::LetIn> {
222    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
223        let mut map = serializer.serialize_map(Some(3))?;
224        map.serialize_entry("kind", "let")?;
225
226        map.serialize_entry(
227            "entries",
228            &self
229                .0
230                .attrpath_values()
231                .map(SerializeAST)
232                .collect::<Vec<_>>(),
233        )?;
234
235        map.serialize_entry(
236            "inherits",
237            &self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
238        )?;
239
240        map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
241        map.end()
242    }
243}
244
245impl Serialize for SerializeAST<&ast::List> {
246    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
247        let list = self.0.items().map(SerializeAST).collect::<Vec<_>>();
248
249        let mut map = serializer.serialize_map(Some(2))?;
250        map.serialize_entry("kind", "list")?;
251        map.serialize_entry("items", &list)?;
252
253        map.end()
254    }
255}
256
257impl Serialize for SerializeAST<&ast::BinOp> {
258    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
259        let mut map = serializer.serialize_map(Some(4))?;
260        map.serialize_entry("kind", "binary_op")?;
261
262        map.serialize_entry(
263            "operator",
264            match self.0.operator().unwrap() {
265                ast::BinOpKind::Concat => "concat",
266                ast::BinOpKind::Update => "update",
267                ast::BinOpKind::Add => "add",
268                ast::BinOpKind::Sub => "sub",
269                ast::BinOpKind::Mul => "mul",
270                ast::BinOpKind::Div => "div",
271                ast::BinOpKind::And => "and",
272                ast::BinOpKind::Equal => "equal",
273                ast::BinOpKind::Implication => "implication",
274                ast::BinOpKind::Less => "less",
275                ast::BinOpKind::LessOrEq => "less_or_eq",
276                ast::BinOpKind::More => "more",
277                ast::BinOpKind::MoreOrEq => "more_or_eq",
278                ast::BinOpKind::NotEqual => "not_equal",
279                ast::BinOpKind::Or => "or",
280            },
281        )?;
282
283        map.serialize_entry("lhs", &SerializeAST(&self.0.lhs().unwrap()))?;
284        map.serialize_entry("rhs", &SerializeAST(&self.0.rhs().unwrap()))?;
285        map.end()
286    }
287}
288
289impl Serialize for SerializeAST<&ast::Paren> {
290    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
291        let mut map = serializer.serialize_map(Some(2))?;
292        map.serialize_entry("kind", "paren")?;
293        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
294        map.end()
295    }
296}
297
298impl Serialize for SerializeAST<&ast::Root> {
299    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
300        let mut map = serializer.serialize_map(Some(2))?;
301        map.serialize_entry("kind", "root")?;
302        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
303        map.end()
304    }
305}
306
307impl Serialize for SerializeAST<ast::AttrpathValue> {
308    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
309        let mut map = serializer.serialize_map(Some(2))?;
310        map.serialize_entry("name", &SerializeAST(self.0.attrpath().unwrap()))?;
311        map.serialize_entry("value", &SerializeAST(self.0.value().unwrap()))?;
312        map.end()
313    }
314}
315
316impl Serialize for SerializeAST<ast::Inherit> {
317    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
318        let mut map = serializer.serialize_map(None)?;
319
320        if let Some(from) = self.0.from() {
321            map.serialize_entry("namespace", &SerializeAST(&from.expr().unwrap()))?;
322        }
323
324        map.serialize_entry(
325            "names",
326            &self.0.attrs().map(SerializeAST).collect::<Vec<_>>(),
327        )?;
328
329        map.end()
330    }
331}
332
333impl Serialize for SerializeAST<&ast::AttrSet> {
334    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
335        let mut map = serializer.serialize_map(None)?;
336        map.serialize_entry("kind", "attrset")?;
337        map.serialize_entry("recursive", &self.0.rec_token().is_some())?;
338
339        map.serialize_entry(
340            "entries",
341            &self
342                .0
343                .attrpath_values()
344                .map(SerializeAST)
345                .collect::<Vec<_>>(),
346        )?;
347
348        map.serialize_entry(
349            "inherits",
350            &self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
351        )?;
352
353        map.end()
354    }
355}
356
357impl Serialize for SerializeAST<&ast::UnaryOp> {
358    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
359        let mut map = serializer.serialize_map(Some(3))?;
360        map.serialize_entry("kind", "unary_op")?;
361
362        map.serialize_entry(
363            "operator",
364            match self.0.operator().unwrap() {
365                ast::UnaryOpKind::Invert => "invert",
366                ast::UnaryOpKind::Negate => "negate",
367            },
368        )?;
369
370        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
371        map.end()
372    }
373}
374
375impl Serialize for SerializeAST<&ast::Ident> {
376    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
377        let mut map = serializer.serialize_map(Some(2))?;
378        map.serialize_entry("kind", "ident")?;
379        map.serialize_entry("ident", self.0.ident_token().unwrap().text())?;
380        map.end()
381    }
382}
383
384impl Serialize for SerializeAST<&ast::With> {
385    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
386        let mut map = serializer.serialize_map(Some(3))?;
387        map.serialize_entry("kind", "with")?;
388        map.serialize_entry("with", &SerializeAST(&self.0.namespace().unwrap()))?;
389        map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
390        map.end()
391    }
392}
393
394impl Serialize for SerializeAST<&ast::Dynamic> {
395    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
396        let mut map = serializer.serialize_map(Some(2))?;
397        map.serialize_entry("kind", "dynamic")?;
398        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
399        map.end()
400    }
401}
402
403impl Serialize for SerializeAST<ast::Attr> {
404    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
405        match &self.0 {
406            ast::Attr::Ident(ident) => Serialize::serialize(&SerializeAST(ident), serializer),
407            ast::Attr::Dynamic(node) => Serialize::serialize(&SerializeAST(node), serializer),
408            ast::Attr::Str(node) => Serialize::serialize(&SerializeAST(node), serializer),
409        }
410    }
411}
412
413impl Serialize for SerializeAST<ast::Attrpath> {
414    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
415        let mut map = serializer.serialize_map(Some(2))?;
416        map.serialize_entry("kind", "attrpath")?;
417
418        map.serialize_entry(
419            "path",
420            &self.0.attrs().map(SerializeAST).collect::<Vec<_>>(),
421        )?;
422
423        map.end()
424    }
425}
426
427impl Serialize for SerializeAST<&ast::HasAttr> {
428    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
429        let mut map = serializer.serialize_map(Some(3))?;
430        map.serialize_entry("kind", "has_attr")?;
431        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
432        map.serialize_entry("attrpath", &SerializeAST(self.0.attrpath().unwrap()))?;
433        map.end()
434    }
435}
436
437impl Serialize for SerializeAST<&ast::Expr> {
438    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
439        match self.0 {
440            ast::Expr::Apply(node) => Serialize::serialize(&SerializeAST(node), serializer),
441            ast::Expr::Assert(node) => Serialize::serialize(&SerializeAST(node), serializer),
442            ast::Expr::Error(node) => Serialize::serialize(&SerializeAST(node), serializer),
443            ast::Expr::IfElse(node) => Serialize::serialize(&SerializeAST(node), serializer),
444            ast::Expr::Select(node) => Serialize::serialize(&SerializeAST(node), serializer),
445            ast::Expr::Str(node) => Serialize::serialize(&SerializeAST(node), serializer),
446            ast::Expr::Path(node) => Serialize::serialize(&SerializeAST(node), serializer),
447            ast::Expr::Literal(node) => Serialize::serialize(&SerializeAST(node), serializer),
448            ast::Expr::Lambda(node) => Serialize::serialize(&SerializeAST(node), serializer),
449            ast::Expr::LegacyLet(node) => Serialize::serialize(&SerializeAST(node), serializer),
450            ast::Expr::LetIn(node) => Serialize::serialize(&SerializeAST(node), serializer),
451            ast::Expr::List(node) => Serialize::serialize(&SerializeAST(node), serializer),
452            ast::Expr::BinOp(node) => Serialize::serialize(&SerializeAST(node), serializer),
453            ast::Expr::Paren(node) => Serialize::serialize(&SerializeAST(node), serializer),
454            ast::Expr::Root(node) => Serialize::serialize(&SerializeAST(node), serializer),
455            ast::Expr::AttrSet(node) => Serialize::serialize(&SerializeAST(node), serializer),
456            ast::Expr::UnaryOp(node) => Serialize::serialize(&SerializeAST(node), serializer),
457            ast::Expr::Ident(node) => Serialize::serialize(&SerializeAST(node), serializer),
458            ast::Expr::With(node) => Serialize::serialize(&SerializeAST(node), serializer),
459            ast::Expr::HasAttr(node) => Serialize::serialize(&SerializeAST(node), serializer),
460        }
461    }
462}
463
464impl Serialize for SerializeAST<ast::Expr> {
465    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
466        SerializeAST(&self.0).serialize(serializer)
467    }
468}