makefile_lossless/
parse.rs1use crate::lossless::{Error, ErrorInfo, Makefile, ParseError, PositionedParseError, 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 positioned_errors: Vec<PositionedParseError>,
17 _ty: PhantomData<T>,
18}
19
20impl<T> Parse<T> {
21 pub fn new(
23 green: GreenNode,
24 errors: Vec<ErrorInfo>,
25 positioned_errors: Vec<PositionedParseError>,
26 ) -> Self {
27 Parse {
28 green,
29 errors,
30 positioned_errors,
31 _ty: PhantomData,
32 }
33 }
34
35 pub fn green(&self) -> &GreenNode {
37 &self.green
38 }
39
40 pub fn errors(&self) -> &[ErrorInfo] {
42 &self.errors
43 }
44
45 pub fn positioned_errors(&self) -> &[PositionedParseError] {
47 &self.positioned_errors
48 }
49
50 pub fn ok(&self) -> bool {
52 self.errors.is_empty()
53 }
54
55 pub fn to_result(self) -> Result<T, Error>
57 where
58 T: AstNode<Language = crate::lossless::Lang>,
59 {
60 if self.errors.is_empty() {
61 let node = SyntaxNode::new_root_mut(self.green);
62 Ok(T::cast(node).expect("root node has wrong type"))
63 } else {
64 Err(Error::Parse(ParseError {
65 errors: self.errors,
66 }))
67 }
68 }
69
70 pub fn tree(&self) -> T
76 where
77 T: AstNode<Language = crate::lossless::Lang>,
78 {
79 let node = SyntaxNode::new_root_mut(self.green.clone());
80 T::cast(node).expect("root node has wrong type")
81 }
82
83 pub fn syntax_node(&self) -> SyntaxNode<crate::lossless::Lang> {
85 SyntaxNode::new_root(self.green.clone())
86 }
87}
88
89unsafe impl<T> Send for Parse<T> {}
91unsafe impl<T> Sync for Parse<T> {}
92
93impl Parse<Makefile> {
94 pub fn parse_makefile(text: &str) -> Self {
96 let parsed = crate::lossless::parse(text, None);
97 Parse::new(parsed.green_node, parsed.errors, parsed.positioned_errors)
98 }
99}
100
101impl Parse<Rule> {
102 pub fn parse_rule(text: &str) -> Self {
104 let parsed = crate::lossless::parse(text, None);
105 Parse::new(parsed.green_node, parsed.errors, parsed.positioned_errors)
106 }
107
108 pub fn to_rule_result(self) -> Result<Rule, Error> {
110 if !self.errors.is_empty() {
111 return Err(Error::Parse(ParseError {
112 errors: self.errors,
113 }));
114 }
115
116 let makefile =
117 Makefile::cast(SyntaxNode::new_root_mut(self.green)).expect("root node has wrong type");
118 let rules: Vec<_> = makefile.rules().collect();
119
120 if rules.len() == 1 {
121 Ok(rules.into_iter().next().unwrap())
122 } else {
123 Err(Error::Parse(ParseError {
124 errors: vec![ErrorInfo {
125 message: "expected a single rule".to_string(),
126 line: 1,
127 context: "".to_string(),
128 }],
129 }))
130 }
131 }
132}