wagon_parser/parser/
metadata.rs

1use crate::parser::helpers::{check_semi, check_colon};
2use wagon_ident::Ident;
3use wagon_macros::match_error;
4use std::{collections::BTreeMap, fmt::Display};
5
6use super::{Parse, LexerBridge, ParseResult, Tokens, WagParseError, atom::Atom, Peek, ResultNext, SpannableNode};
7
8use wagon_macros::new_unspanned;
9
10#[derive(PartialEq, Debug, Eq, Hash)]
11#[new_unspanned]
12/// The metadata of the WAG.
13///
14/// # Grammar
15/// <span><pre>
16/// [Metadata]  -> Meta* MetaDelim;
17/// MetaDelim -> `"=="` `"="`+;
18/// Meta      -> Include | Config;
19/// Include   -> `"include"` Path;
20/// Config    -> Identifier `":"` [Expression](super::expression::Expression) `";"`;
21/// </pre></span>
22pub struct Metadata {
23    /// All imports for this grammar.
24	pub includes: Vec<String>,
25    /// Any extra key-value mappings.
26	pub mappings: BTreeMap<String, SpannableNode<Atom>>
27}
28
29impl Parse for Metadata {
30    fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> {
31        let mut includes = Vec::new();
32        let mut mappings = BTreeMap::new();
33        while let Some(Ok(Tokens::MetadataToken(_))) = lexer.peek() {
34                match_error!(match lexer.next_result()? {
35                    Tokens::MetadataToken(wagon_lexer::metadata::Metadata::Identifier(Ident::Unknown(s))) => {
36                        check_colon(lexer)?;
37                        let atom = SpannableNode::parse(lexer)?;
38                        check_semi(lexer)?;
39                        mappings.insert(s, atom);
40                        Ok(())
41                    },
42                    Tokens::MetadataToken(wagon_lexer::metadata::Metadata::Delim) => break,
43                    Tokens::MetadataToken(wagon_lexer::metadata::Metadata::Include) => {
44                        match_error!(match lexer.next_result()? {
45                            Tokens::MetadataToken(wagon_lexer::metadata::Metadata::Path(p)) => {
46                                includes.push(p); 
47                                check_semi(lexer)?;
48                                Ok(())
49                            }
50                        })
51                    }
52                })?;
53        }
54        Ok(Self { includes, mappings })
55    }
56}
57
58impl Display for Metadata {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        for include in &self.includes {
61            writeln!(f, "include {include};")?;
62        }
63        for (key, value) in &self.mappings {
64            writeln!(f, "{key}: {value};")?;
65        }
66        writeln!(f, "================")
67    }
68}