compose_syntax/ast/
bindings.rs1use crate::ast::func::Pattern;
2use crate::ast::{node, AstNode, Expr, Ident};
3use crate::kind::SyntaxKind;
4use crate::Span;
5
6node! {
7 struct LetBinding
8}
9
10impl<'a> LetBinding<'a> {
11 pub fn has_initial_value(self) -> bool {
12 self.0.children().any(|n| n.kind() == SyntaxKind::Eq)
13 }
14
15 pub fn initial_value(self) -> Option<Expr<'a>> {
16 self.0
17 .children()
18 .skip_while(|n| n.kind() != SyntaxKind::Eq)
19 .nth(1)
20 .and_then(|n| n.cast())
21 }
22
23 fn bindings(self) -> Vec<Ident<'a>> {
24 let pattern: Pattern = self.0.try_cast_first().expect("expected pattern");
25 pattern.bindings()
26 }
27
28 pub fn pattern(self) -> Pattern<'a> {
29 self.0.cast_first()
30 }
31
32 pub fn is_mut(self) -> bool {
33 self.0.children().any(|n| n.kind() == SyntaxKind::Mut)
34 }
35
36 pub fn eq_span(self) -> Span {
37 self.0
38 .children()
39 .find(|&n| n.kind() == SyntaxKind::Eq)
40 .map(|n| n.span())
41 .unwrap_or_else(|| self.0.span())
42 }
43
44 pub fn mut_span(self) -> Option<Span> {
45 self.0
46 .children()
47 .find(|&n| n.kind() == SyntaxKind::Mut)
48 .map(|n| n.span())
49 }
50
51 pub fn initial_value_span(self) -> Option<Span> {
52 self.initial_value().map(|e| e.span())
53 }
54
55 pub fn is_public(self) -> bool {
56 self.0.children().any(|n| n.kind() == SyntaxKind::Pub)
57 }
58
59 pub fn pub_span(self) -> Option<Span> {
60 self.0
61 .children()
62 .find(|&n| n.kind() == SyntaxKind::Pub)
63 .map(|n| n.span())
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::assert_ast;
71 use crate::ast::Int;
72
73 #[test]
74 fn test_let_binding() {
75 assert_ast!(
76 "let x = 1",
77 binding as LetBinding {
78 binding.bindings().into_iter() => [
79 ident as Ident {
80 assert_eq!(ident.get(), "x");
81 }
82 ]
83 with init: Int = binding.initial_value().unwrap() => {
84 assert_eq!(init.get(), 1);
85 }
86 }
87 )
88 }
89}