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, PathContent};
7use serde::{Serialize, Serializer, ser::SerializeMap};
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<Vec<ast::InterpolPart<PathContent>>> {
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.iter().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                ast::BinOpKind::PipeRight => "pipe_right",
281                ast::BinOpKind::PipeLeft => "pipe_left",
282            },
283        )?;
284
285        map.serialize_entry("lhs", &SerializeAST(&self.0.lhs().unwrap()))?;
286        map.serialize_entry("rhs", &SerializeAST(&self.0.rhs().unwrap()))?;
287        map.end()
288    }
289}
290
291impl Serialize for SerializeAST<&ast::Paren> {
292    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
293        let mut map = serializer.serialize_map(Some(2))?;
294        map.serialize_entry("kind", "paren")?;
295        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
296        map.end()
297    }
298}
299
300impl Serialize for SerializeAST<&ast::Root> {
301    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
302        let mut map = serializer.serialize_map(Some(2))?;
303        map.serialize_entry("kind", "root")?;
304        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
305        map.end()
306    }
307}
308
309impl Serialize for SerializeAST<ast::AttrpathValue> {
310    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
311        let mut map = serializer.serialize_map(Some(2))?;
312        map.serialize_entry("name", &SerializeAST(self.0.attrpath().unwrap()))?;
313        map.serialize_entry("value", &SerializeAST(self.0.value().unwrap()))?;
314        map.end()
315    }
316}
317
318impl Serialize for SerializeAST<ast::Inherit> {
319    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
320        let mut map = serializer.serialize_map(None)?;
321
322        if let Some(from) = self.0.from() {
323            map.serialize_entry("namespace", &SerializeAST(&from.expr().unwrap()))?;
324        }
325
326        map.serialize_entry(
327            "names",
328            &self.0.attrs().map(SerializeAST).collect::<Vec<_>>(),
329        )?;
330
331        map.end()
332    }
333}
334
335impl Serialize for SerializeAST<&ast::AttrSet> {
336    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
337        let mut map = serializer.serialize_map(None)?;
338        map.serialize_entry("kind", "attrset")?;
339        map.serialize_entry("recursive", &self.0.rec_token().is_some())?;
340
341        map.serialize_entry(
342            "entries",
343            &self
344                .0
345                .attrpath_values()
346                .map(SerializeAST)
347                .collect::<Vec<_>>(),
348        )?;
349
350        map.serialize_entry(
351            "inherits",
352            &self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
353        )?;
354
355        map.end()
356    }
357}
358
359impl Serialize for SerializeAST<&ast::UnaryOp> {
360    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
361        let mut map = serializer.serialize_map(Some(3))?;
362        map.serialize_entry("kind", "unary_op")?;
363
364        map.serialize_entry(
365            "operator",
366            match self.0.operator().unwrap() {
367                ast::UnaryOpKind::Invert => "invert",
368                ast::UnaryOpKind::Negate => "negate",
369            },
370        )?;
371
372        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
373        map.end()
374    }
375}
376
377impl Serialize for SerializeAST<&ast::Ident> {
378    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
379        let mut map = serializer.serialize_map(Some(2))?;
380        map.serialize_entry("kind", "ident")?;
381        map.serialize_entry("ident", self.0.ident_token().unwrap().text())?;
382        map.end()
383    }
384}
385
386impl Serialize for SerializeAST<&ast::With> {
387    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
388        let mut map = serializer.serialize_map(Some(3))?;
389        map.serialize_entry("kind", "with")?;
390        map.serialize_entry("with", &SerializeAST(&self.0.namespace().unwrap()))?;
391        map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
392        map.end()
393    }
394}
395
396impl Serialize for SerializeAST<&ast::Dynamic> {
397    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
398        let mut map = serializer.serialize_map(Some(2))?;
399        map.serialize_entry("kind", "dynamic")?;
400        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
401        map.end()
402    }
403}
404
405impl Serialize for SerializeAST<ast::Attr> {
406    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
407        match &self.0 {
408            ast::Attr::Ident(ident) => Serialize::serialize(&SerializeAST(ident), serializer),
409            ast::Attr::Dynamic(node) => Serialize::serialize(&SerializeAST(node), serializer),
410            ast::Attr::Str(node) => Serialize::serialize(&SerializeAST(node), serializer),
411        }
412    }
413}
414
415impl Serialize for SerializeAST<ast::Attrpath> {
416    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
417        let mut map = serializer.serialize_map(Some(2))?;
418        map.serialize_entry("kind", "attrpath")?;
419
420        map.serialize_entry(
421            "path",
422            &self.0.attrs().map(SerializeAST).collect::<Vec<_>>(),
423        )?;
424
425        map.end()
426    }
427}
428
429impl Serialize for SerializeAST<&ast::HasAttr> {
430    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
431        let mut map = serializer.serialize_map(Some(3))?;
432        map.serialize_entry("kind", "has_attr")?;
433        map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
434        map.serialize_entry("attrpath", &SerializeAST(self.0.attrpath().unwrap()))?;
435        map.end()
436    }
437}
438
439impl Serialize for SerializeAST<&ast::CurPos> {
440    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
441        let mut map = serializer.serialize_map(Some(1))?;
442        map.serialize_entry("kind", "cur_pos")?;
443        map.end()
444    }
445}
446
447impl Serialize for SerializeAST<&ast::Expr> {
448    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
449        match self.0 {
450            ast::Expr::Apply(node) => Serialize::serialize(&SerializeAST(node), serializer),
451            ast::Expr::Assert(node) => Serialize::serialize(&SerializeAST(node), serializer),
452            ast::Expr::Error(node) => Serialize::serialize(&SerializeAST(node), serializer),
453            ast::Expr::IfElse(node) => Serialize::serialize(&SerializeAST(node), serializer),
454            ast::Expr::Select(node) => Serialize::serialize(&SerializeAST(node), serializer),
455            ast::Expr::Str(node) => Serialize::serialize(&SerializeAST(node), serializer),
456            ast::Expr::PathAbs(path) => {
457                Serialize::serialize(&SerializeAST(path.parts()), serializer)
458            }
459            ast::Expr::PathHome(path) => {
460                Serialize::serialize(&SerializeAST(path.parts()), serializer)
461            }
462            ast::Expr::PathRel(path) => {
463                Serialize::serialize(&SerializeAST(path.parts()), serializer)
464            }
465            ast::Expr::PathSearch(path) => {
466                let part = ast::InterpolPart::Literal(path.content().unwrap());
467                Serialize::serialize(&SerializeAST(&part), serializer)
468            }
469            ast::Expr::Literal(node) => Serialize::serialize(&SerializeAST(node), serializer),
470            ast::Expr::Lambda(node) => Serialize::serialize(&SerializeAST(node), serializer),
471            ast::Expr::LegacyLet(node) => Serialize::serialize(&SerializeAST(node), serializer),
472            ast::Expr::LetIn(node) => Serialize::serialize(&SerializeAST(node), serializer),
473            ast::Expr::List(node) => Serialize::serialize(&SerializeAST(node), serializer),
474            ast::Expr::BinOp(node) => Serialize::serialize(&SerializeAST(node), serializer),
475            ast::Expr::Paren(node) => Serialize::serialize(&SerializeAST(node), serializer),
476            ast::Expr::Root(node) => Serialize::serialize(&SerializeAST(node), serializer),
477            ast::Expr::AttrSet(node) => Serialize::serialize(&SerializeAST(node), serializer),
478            ast::Expr::UnaryOp(node) => Serialize::serialize(&SerializeAST(node), serializer),
479            ast::Expr::Ident(node) => Serialize::serialize(&SerializeAST(node), serializer),
480            ast::Expr::With(node) => Serialize::serialize(&SerializeAST(node), serializer),
481            ast::Expr::HasAttr(node) => Serialize::serialize(&SerializeAST(node), serializer),
482            ast::Expr::CurPos(node) => Serialize::serialize(&SerializeAST(node), serializer),
483        }
484    }
485}
486
487impl Serialize for SerializeAST<ast::Expr> {
488    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
489        SerializeAST(&self.0).serialize(serializer)
490    }
491}