makefile_lossless/
parse.rs1use crate::lossless::{Error, ErrorInfo, Makefile, ParseError, Rule};
4use rowan::ast::AstNode;
5use rowan::{GreenNode, SyntaxNode};
6use std::marker::PhantomData;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Parse<T> {
14 green: GreenNode,
15 errors: Vec<ErrorInfo>,
16 _ty: PhantomData<T>,
17}
18
19impl<T> Parse<T> {
20 pub fn new(green: GreenNode, errors: Vec<ErrorInfo>) -> Self {
22 Parse {
23 green,
24 errors,
25 _ty: PhantomData,
26 }
27 }
28
29 pub fn green(&self) -> &GreenNode {
31 &self.green
32 }
33
34 pub fn errors(&self) -> &[ErrorInfo] {
36 &self.errors
37 }
38
39 pub fn ok(&self) -> bool {
41 self.errors.is_empty()
42 }
43
44 pub fn to_result(self) -> Result<T, Error>
46 where
47 T: AstNode<Language = crate::lossless::Lang>,
48 {
49 if self.errors.is_empty() {
50 let node = SyntaxNode::new_root_mut(self.green);
51 Ok(T::cast(node).expect("root node has wrong type"))
52 } else {
53 Err(Error::Parse(ParseError {
54 errors: self.errors,
55 }))
56 }
57 }
58
59 pub fn tree(&self) -> T
61 where
62 T: AstNode<Language = crate::lossless::Lang>,
63 {
64 assert!(
65 self.errors.is_empty(),
66 "tried to get tree with errors: {:?}",
67 self.errors
68 );
69 let node = SyntaxNode::new_root_mut(self.green.clone());
70 T::cast(node).expect("root node has wrong type")
71 }
72
73 pub fn syntax_node(&self) -> SyntaxNode<crate::lossless::Lang> {
75 SyntaxNode::new_root(self.green.clone())
76 }
77}
78
79unsafe impl<T> Send for Parse<T> {}
81unsafe impl<T> Sync for Parse<T> {}
82
83impl Parse<Makefile> {
84 pub fn parse_makefile(text: &str) -> Self {
86 let parsed = crate::lossless::parse(text);
87 Parse::new(parsed.green_node, parsed.errors)
88 }
89}
90
91impl Parse<Rule> {
92 pub fn parse_rule(text: &str) -> Self {
94 let parsed = crate::lossless::parse(text);
95 Parse::new(parsed.green_node, parsed.errors)
96 }
97
98 pub fn to_rule_result(self) -> Result<Rule, Error> {
100 if !self.errors.is_empty() {
101 return Err(Error::Parse(ParseError {
102 errors: self.errors,
103 }));
104 }
105
106 let makefile =
107 Makefile::cast(SyntaxNode::new_root_mut(self.green)).expect("root node has wrong type");
108 let rules: Vec<_> = makefile.rules().collect();
109
110 if rules.len() == 1 {
111 Ok(rules.into_iter().next().unwrap())
112 } else {
113 Err(Error::Parse(ParseError {
114 errors: vec![ErrorInfo {
115 message: "expected a single rule".to_string(),
116 line: 1,
117 context: "".to_string(),
118 }],
119 }))
120 }
121 }
122}