static_graph/parser/
document.rs

1use nom::{
2    branch::alt,
3    combinator::{map, opt},
4    multi::many0,
5    sequence::tuple,
6    IResult,
7};
8
9use super::{blank, graph::Graph, node::Node, Parser};
10
11#[derive(Debug, Clone)]
12pub struct Document {
13    pub graphs: Vec<Graph>,
14    pub nodes: Vec<Node>,
15}
16
17impl<'a> Parser<'a> for Document {
18    fn parse(input: &'a str) -> IResult<&'a str, Self> {
19        enum NodeOrGraph {
20            Node(Node),
21            Graph(Graph),
22        }
23        map(
24            many0(map(
25                tuple((
26                    opt(blank),
27                    alt((
28                        map(Node::parse, NodeOrGraph::Node),
29                        map(Graph::parse, NodeOrGraph::Graph),
30                    )),
31                    opt(blank),
32                )),
33                |(_, nog, _)| nog,
34            )),
35            |nogs| {
36                let mut graphs = Vec::new();
37                let mut nodes = Vec::new();
38                for nog in nogs.into_iter() {
39                    match nog {
40                        NodeOrGraph::Node(node) => nodes.push(node),
41                        NodeOrGraph::Graph(graph) => graphs.push(graph),
42                    }
43                }
44                Document { graphs, nodes }
45            },
46        )(input)
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_document() {
56        let input = r#"
57        graph Foo(Bar)
58
59        node Bar -> (Baz, Qux) {
60            #[default = "B::new"]
61            b: B,
62        }
63
64        node Baz -> Out {
65            #[default = "C::new"]
66            c: C,
67        }
68
69        node Qux -> Out {
70            #[default = "D::new"]
71            d: D,
72        }
73
74        node Out {
75
76        }
77        "#;
78
79        match super::Document::parse(input) {
80            Ok((remain, doc)) => {
81                assert_eq!(remain, "");
82                assert_eq!(doc.graphs.len(), 1);
83                assert_eq!(doc.nodes.len(), 4);
84            }
85            Err(e) => panic!("Error: {e:?}"),
86        }
87    }
88}