rnix/ast/
path_util.rs

1use crate::{ast::AstToken, kinds::SyntaxKind::*};
2use rowan::{ast::AstNode as OtherAstNode, NodeOrToken};
3
4use crate::ast;
5
6use super::{InterpolPart, PathContent};
7
8impl ast::nodes::Path {
9    pub fn parts(&self) -> impl Iterator<Item = InterpolPart<PathContent>> {
10        self.syntax().children_with_tokens().map(|child| match child {
11            NodeOrToken::Token(token) => {
12                assert_eq!(token.kind(), TOKEN_PATH);
13                InterpolPart::Literal(PathContent::cast(token).unwrap())
14            }
15            NodeOrToken::Node(node) => {
16                InterpolPart::Interpolation(ast::Interpol::cast(node.clone()).unwrap())
17            }
18        })
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use rowan::ast::AstNode;
25
26    use crate::{
27        ast::{self, AstToken, InterpolPart, PathContent},
28        Root,
29    };
30
31    #[test]
32    fn parts() {
33        fn assert_eq_ast_ctn(it: &mut dyn Iterator<Item = InterpolPart<PathContent>>, x: &str) {
34            let tmp = it.next().expect("unexpected EOF");
35            if let InterpolPart::Interpolation(astn) = tmp {
36                assert_eq!(astn.expr().unwrap().syntax().to_string(), x);
37            } else {
38                unreachable!("unexpected literal {:?}", tmp);
39            }
40        }
41
42        fn assert_eq_lit(it: &mut dyn Iterator<Item = InterpolPart<PathContent>>, x: &str) {
43            let tmp = it.next().expect("unexpected EOF");
44            if let InterpolPart::Literal(astn) = tmp {
45                assert_eq!(astn.syntax().text(), x);
46            } else {
47                unreachable!("unexpected interpol {:?}", tmp);
48            }
49        }
50
51        let inp = r#"./a/b/${"c"}/${d}/e/f"#;
52        let expr = Root::parse(inp).ok().unwrap().expr().unwrap();
53        match expr {
54            ast::Expr::Path(p) => {
55                let mut it = p.parts();
56                assert_eq_lit(&mut it, "./a/b/");
57                assert_eq_ast_ctn(&mut it, "\"c\"");
58                assert_eq_lit(&mut it, "/");
59                assert_eq_ast_ctn(&mut it, "d");
60                assert_eq_lit(&mut it, "/e/f");
61            }
62            _ => unreachable!(),
63        }
64    }
65}