1use rowan::GreenNode;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Parse<T> {
12 green_node: GreenNode,
13 positioned_errors: Vec<crate::PositionedParseError>,
14 _ty: std::marker::PhantomData<fn() -> T>,
15}
16
17impl<T> Parse<T> {
18 pub(crate) fn new(
19 green_node: GreenNode,
20 positioned_errors: Vec<crate::PositionedParseError>,
21 ) -> Self {
22 Parse {
23 green_node,
24 positioned_errors,
25 _ty: std::marker::PhantomData,
26 }
27 }
28
29 pub fn tree(&self) -> T
32 where
33 T: rowan::ast::AstNode<Language = crate::Lang>,
34 {
35 let syntax_node = rowan::SyntaxNode::new_root_mut(self.green_node.clone());
36 T::cast(syntax_node)
37 .expect("Parse<T> always holds a green node whose root kind matches T::can_cast")
38 }
39
40 pub fn positioned_errors(&self) -> &[crate::PositionedParseError] {
42 &self.positioned_errors
43 }
44
45 pub fn errors(&self) -> Vec<String> {
47 self.positioned_errors
48 .iter()
49 .map(|e| e.message.clone())
50 .collect()
51 }
52
53 pub fn to_result(self) -> Result<T, crate::YamlError>
61 where
62 T: rowan::ast::AstNode<Language = crate::Lang>,
63 {
64 if let Some(first) = self.positioned_errors.first() {
65 Err(crate::YamlError::Parse {
66 message: first.message.clone(),
67 line: None,
68 column: None,
69 })
70 } else {
71 Ok(self.tree())
72 }
73 }
74
75 pub fn has_errors(&self) -> bool {
77 !self.positioned_errors.is_empty()
78 }
79
80 pub fn ok(&self) -> bool {
82 self.positioned_errors.is_empty()
83 }
84}
85
86impl Parse<crate::YamlFile> {
87 pub fn parse_yaml(text: &str) -> Self {
89 let parsed = crate::yaml::parse(text);
90 Parse::new(parsed.green_node, parsed.positioned_errors)
91 }
92}