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
64 where
65 T: AstNode<Language = crate::lossless::Lang>,
66 {
67 let node = SyntaxNode::new_root_mut(self.green.clone());
68 T::cast(node).expect("root node has wrong type")
69 }
70
71 pub fn syntax_node(&self) -> SyntaxNode<crate::lossless::Lang> {
73 SyntaxNode::new_root(self.green.clone())
74 }
75}
76
77unsafe impl<T> Send for Parse<T> {}
79unsafe impl<T> Sync for Parse<T> {}
80
81impl Parse<Makefile> {
82 pub fn parse_makefile(text: &str) -> Self {
84 let parsed = crate::lossless::parse(text, None);
85 Parse::new(parsed.green_node, parsed.errors)
86 }
87}
88
89impl Parse<Rule> {
90 pub fn parse_rule(text: &str) -> Self {
92 let parsed = crate::lossless::parse(text, None);
93 Parse::new(parsed.green_node, parsed.errors)
94 }
95
96 pub fn to_rule_result(self) -> Result<Rule, Error> {
98 if !self.errors.is_empty() {
99 return Err(Error::Parse(ParseError {
100 errors: self.errors,
101 }));
102 }
103
104 let makefile =
105 Makefile::cast(SyntaxNode::new_root_mut(self.green)).expect("root node has wrong type");
106 let rules: Vec<_> = makefile.rules().collect();
107
108 if rules.len() == 1 {
109 Ok(rules.into_iter().next().unwrap())
110 } else {
111 Err(Error::Parse(ParseError {
112 errors: vec![ErrorInfo {
113 message: "expected a single rule".to_string(),
114 line: 1,
115 context: "".to_string(),
116 }],
117 }))
118 }
119 }
120}