static_graph/parser/
node.rs

1use super::{blank, field::Field, ident::Ident, list_separator, Parser};
2
3use nom::{
4    bytes::complete::tag,
5    combinator::map,
6    combinator::opt,
7    multi::many0,
8    multi::separated_list0,
9    sequence::{delimited, tuple},
10    IResult,
11};
12
13#[derive(Debug, Clone)]
14pub struct Node {
15    pub name: Ident,
16    pub to_nodes: Vec<Ident>,
17    pub fields: Vec<Field>,
18}
19
20impl<'a> Parser<'a> for Node {
21    fn parse(input: &'a str) -> IResult<&'a str, Self> {
22        map(
23            tuple((
24                tag("node"),
25                blank,
26                Ident::parse,
27                opt(blank),
28                opt(map(
29                    tuple((
30                        tag("->"),
31                        opt(blank),
32                        delimited(
33                            opt(tag("(")),
34                            many0(map(
35                                tuple((opt(blank), Ident::parse, opt(list_separator))),
36                                |(_, to_ident, _)| to_ident,
37                            )),
38                            opt(tag(")")),
39                        ),
40                        opt(blank),
41                    )),
42                    |(_, _, to_idents, _)| to_idents,
43                )),
44                tag("{"),
45                opt(blank),
46                separated_list0(blank, Field::parse),
47                opt(blank),
48                tag("}"),
49            )),
50            |(_, _, name, _, to_nodes, _, _, fields, _, _)| Node {
51                name,
52                to_nodes: to_nodes.unwrap_or_default(),
53                fields,
54            },
55        )(input)
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use crate::parser::ty::Type;
63
64    #[test]
65    fn test_node() {
66        let input = r#"node Foo {
67            #[default = "Bar::new"]
68            foo: Bar,
69        }"#;
70        match super::Node::parse(input) {
71            Ok((remain, node)) => {
72                assert_eq!(remain, "");
73                assert_eq!(node.name.0, "Foo");
74                assert_eq!(node.to_nodes.len(), 0);
75                assert_eq!(node.fields.len(), 1);
76                assert_eq!(node.fields[0].name.0, "foo");
77                match &node.fields[0].ty {
78                    Type::Path(path) => {
79                        assert_eq!(path.segments.len(), 1);
80                        assert_eq!(path.segments[0].0, "Bar");
81                    }
82                    _ => panic!("Expected Path"),
83                }
84                assert_eq!(node.fields[0].annotations.len(), 1);
85                assert_eq!(node.fields[0].annotations[0].key, "default");
86            }
87            Err(e) => panic!("Error: {e:?}"),
88        }
89    }
90}