pest_generator/
docs.rs
1use pest::iterators::Pairs;
4use pest_meta::parser::Rule;
5use std::collections::HashMap;
6
7#[derive(Debug)]
9pub struct DocComment {
10 pub grammar_doc: String,
12
13 pub line_docs: HashMap<String, String>,
16}
17
18pub fn consume(pairs: Pairs<'_, Rule>) -> DocComment {
41 let mut grammar_doc = String::new();
42
43 let mut line_docs: HashMap<String, String> = HashMap::new();
44 let mut line_doc = String::new();
45
46 for pair in pairs {
47 match pair.as_rule() {
48 Rule::grammar_doc => {
49 let inner_doc = pair.into_inner().next().unwrap();
51 grammar_doc.push_str(inner_doc.as_str());
52 grammar_doc.push('\n');
53 }
54 Rule::grammar_rule => {
55 if let Some(inner) = pair.into_inner().next() {
56 match inner.as_rule() {
58 Rule::line_doc => {
59 if let Some(inner_doc) = inner.into_inner().next() {
60 line_doc.push_str(inner_doc.as_str());
61 line_doc.push('\n');
62 }
63 }
64 Rule::identifier => {
65 if !line_doc.is_empty() {
66 let rule_name = inner.as_str().to_owned();
67
68 line_doc.pop();
70 line_docs.insert(rule_name, line_doc.clone());
71 line_doc.clear();
72 }
73 }
74 _ => (),
75 }
76 }
77 }
78 _ => (),
79 }
80 }
81
82 if !grammar_doc.is_empty() {
83 grammar_doc.pop();
85 }
86
87 DocComment {
88 grammar_doc,
89 line_docs,
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use std::collections::HashMap;
96
97 use pest_meta::parser;
98 use pest_meta::parser::Rule;
99
100 #[test]
101 fn test_doc_comment() {
102 let pairs = match parser::parse(Rule::grammar_rules, include_str!("../tests/test.pest")) {
103 Ok(pairs) => pairs,
104 Err(_) => panic!("error parsing tests/test.pest"),
105 };
106
107 let doc_comment = super::consume(pairs);
108
109 let mut expected = HashMap::new();
110 expected.insert("foo".to_owned(), "Matches foo str, e.g.: `foo`".to_owned());
111 expected.insert(
112 "bar".to_owned(),
113 "Matches bar str\n\n Indent 2, e.g: `bar` or `foobar`".to_owned(),
114 );
115 expected.insert(
116 "dar".to_owned(),
117 "Matches dar\n\nMatch dar description\n".to_owned(),
118 );
119 assert_eq!(expected, doc_comment.line_docs);
120
121 assert_eq!(
122 "A parser for JSON file.\nAnd this is a example for JSON parser.\n\n indent-4-space\n",
123 doc_comment.grammar_doc
124 );
125 }
126
127 #[test]
128 fn test_empty_grammar_doc() {
129 assert!(parser::parse(Rule::grammar_rules, "//!").is_ok());
130 assert!(parser::parse(Rule::grammar_rules, "///").is_ok());
131 assert!(parser::parse(Rule::grammar_rules, "//").is_ok());
132 assert!(parser::parse(Rule::grammar_rules, "/// Line Doc").is_ok());
133 assert!(parser::parse(Rule::grammar_rules, "//! Grammar Doc").is_ok());
134 assert!(parser::parse(Rule::grammar_rules, "// Comment").is_ok());
135 }
136}