badness_parser/bib/
core.rs1use rowan::GreenNode;
8
9use crate::bib::grammar;
10use crate::bib::lexer::lex;
11use crate::bib::syntax::SyntaxNode;
12use crate::bib::tree_builder::build_tree;
13
14pub use crate::SyntaxError;
15
16#[derive(Debug, Clone)]
19pub struct Parse {
20 pub green: GreenNode,
21 pub errors: Vec<SyntaxError>,
22}
23
24impl Parse {
25 pub fn syntax(&self) -> SyntaxNode {
28 SyntaxNode::new_root(self.green.clone())
29 }
30}
31
32pub fn parse(input: &str) -> Parse {
34 let tokens = lex(input);
35 let (events, errors) = grammar::parse(&tokens);
36 let green = build_tree(&tokens, &events);
37 Parse { green, errors }
38}
39
40pub fn reconstruct(input: &str) -> String {
43 parse(input).syntax().to_string()
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use crate::bib::syntax::SyntaxKind;
50
51 #[test]
52 fn reconstruct_is_identity() {
53 let input = "@article{key,\n title = {Hi},\n year = 2020,\n}\n";
54 assert_eq!(reconstruct(input), input);
55 }
56
57 #[test]
58 fn entry_has_key_and_fields() {
59 let parse = parse("@article{key, title = {Hi}}");
60 let entry = parse
61 .syntax()
62 .descendants()
63 .find(|n| n.kind() == SyntaxKind::ENTRY)
64 .expect("an ENTRY node");
65 assert!(
66 entry.children().any(|n| n.kind() == SyntaxKind::KEY),
67 "the entry should have a KEY node"
68 );
69 assert!(
70 entry.children().any(|n| n.kind() == SyntaxKind::FIELD),
71 "the entry should have a FIELD node"
72 );
73 assert!(parse.errors.is_empty());
74 }
75}