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