1use super::{ParseError, ParseErrorKind};
2use crate::Result;
3use pest::Parser as ParseTrait;
4use pest_derive::Parser;
5use std::slice::Iter;
6
7#[derive(Parser)]
8#[grammar = "parsers/grammars/gron.pest"]
9struct GronParser;
10
11pub fn parse(s: &str) -> Result<Statements<'_>, ParseError> {
13 let statements = GronParser::parse(Rule::Statements, s)
14 .map_err(|e| ParseError::new(ParseErrorKind::Gron, e))?
15 .into_iter()
16 .filter_map(|pair| match pair.as_rule() {
17 Rule::Statement => {
18 let mut inner = pair.into_inner();
19 let path = inner.next().unwrap().as_str();
22 let value = inner.next().unwrap().as_str();
23
24 Some(Statement::new(path, value))
25 }
26 Rule::EOI => None,
27 _ => unreachable!(),
28 })
29 .collect();
30
31 Ok(statements)
32}
33
34#[derive(Debug, PartialEq)]
35pub struct Statement<'a> {
36 path: &'a str,
37 value: &'a str,
38}
39
40impl<'a> Statement<'a> {
41 pub fn new(path: &'a str, value: &'a str) -> Self {
42 Self { path, value }
43 }
44
45 pub fn path(&self) -> &'a str {
46 self.path
47 }
48
49 pub fn value(&self) -> &'a str {
50 self.value
51 }
52}
53
54#[derive(Debug, PartialEq)]
55pub struct Statements<'a> {
56 inner: Vec<Statement<'a>>,
57}
58
59impl<'a> Statements<'a> {
60 pub fn iter(&self) -> Iter<'a, Statement> {
61 self.inner.iter()
62 }
63}
64
65impl<'a> FromIterator<Statement<'a>> for Statements<'a> {
66 fn from_iter<T>(iter: T) -> Self
67 where
68 T: IntoIterator<Item = Statement<'a>>,
69 {
70 Self {
71 inner: iter.into_iter().collect(),
72 }
73 }
74}
75
76impl<'a> IntoIterator for Statements<'a> {
77 type Item = Statement<'a>;
78 type IntoIter = std::vec::IntoIter<Self::Item>;
79
80 fn into_iter(self) -> Self::IntoIter {
81 self.inner.into_iter()
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88 use pretty_assertions::assert_eq;
89
90 #[test]
91 fn test_parse() {
92 assert_eq!(
93 parse("foo.bar = \"baz\";").unwrap(),
94 Statements::from_iter(vec![Statement::new("foo.bar", "\"baz\"")])
95 );
96 assert_eq!(
97 parse("foo.bar[5].baz = []").unwrap(),
98 Statements::from_iter(vec![Statement::new("foo.bar[5].baz", "[]")])
99 );
100 assert_eq!(
101 parse("foo = \"bar\"; baz = 1").unwrap(),
102 Statements::from_iter(vec![
103 Statement::new("foo", "\"bar\""),
104 Statement::new("baz", "1")
105 ])
106 );
107 }
108}