Actually just three programming languages in a trenchcoat
1use super::*;
2use crate::{Parser, Spanned};
3use source_span::Span;
4
5/// A binding pattern.
6///
7/// ```trilogy
8/// mut x
9/// ```
10#[derive(Clone, Debug, PrettyPrintSExpr)]
11pub struct BindingPattern {
12 pub mutable: MutModifier,
13 pub identifier: Identifier,
14}
15
16impl BindingPattern {
17 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> {
18 let mutable = MutModifier::parse(parser);
19 let identifier = Identifier::parse(parser)?;
20 Ok(Self {
21 mutable,
22 identifier,
23 })
24 }
25
26 #[inline]
27 pub fn is_immutable(&self) -> bool {
28 matches!(self.mutable, MutModifier::Not)
29 }
30
31 #[inline]
32 pub fn is_mutable(&self) -> bool {
33 matches!(self.mutable, MutModifier::Mut(..))
34 }
35}
36
37impl Spanned for BindingPattern {
38 fn span(&self) -> Span {
39 match &self.mutable {
40 MutModifier::Not => self.identifier.span(),
41 MutModifier::Mut(token) => token.span.union(self.identifier.span()),
42 }
43 }
44}
45
46#[cfg(test)]
47mod test {
48 use super::*;
49
50 test_parse!(binding_immutable: "hello" => BindingPattern::parse => "(BindingPattern () (Identifier))");
51 test_parse!(binding_mutable: "mut hello" => BindingPattern::parse => "(BindingPattern (MutModifier::Mut _) (Identifier))");
52 test_parse_error!(binding_not_name: "mut 'hello" => BindingPattern::parse => "expected identifier");
53 test_parse_error!(binding_multiple: "mut hello, world" => BindingPattern::parse);
54
55 #[test]
56 fn test_is_immutable() {
57 let binding = parse!("hello" => BindingPattern::parse);
58 assert!(binding.is_immutable());
59 }
60
61 #[test]
62 fn test_is_mutable() {
63 let binding = parse!("mut hello" => BindingPattern::parse);
64 assert!(!binding.is_immutable());
65 }
66}