compose_syntax/ast/
assignment.rs

1use crate::ast::Expr;
2use crate::ast::macros::node;
3use crate::kind::SyntaxKind;
4
5node! {
6    struct Assignment
7}
8
9impl<'a> Assignment<'a> {
10    pub fn lhs(self) -> Expr<'a> {
11        self.0.cast_first()
12    }
13    
14    pub fn op(self) -> AssignOp {
15        self.0.children().find_map(|n| AssignOp::from_kind(n.kind()))
16            .unwrap_or(AssignOp::Assign)
17    }
18    
19    pub fn rhs(self) -> Expr<'a> {
20        self.0.cast_last()
21    }
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum AssignOp {
26    Assign,
27    AddAssign,
28    SubAssign,
29    MulAssign,
30    DivAssign,
31    ModAssign,
32}
33
34impl AssignOp {
35    pub(crate) fn from_kind(kind: SyntaxKind) -> Option<Self> {
36        Some(match kind {
37            SyntaxKind::Eq => AssignOp::Assign,
38            SyntaxKind::PlusEq => AssignOp::AddAssign,
39            SyntaxKind::MinusEq => AssignOp::SubAssign,
40            SyntaxKind::StarEq => AssignOp::MulAssign,
41            SyntaxKind::SlashEq => AssignOp::DivAssign,
42            SyntaxKind::AmpersandEq => AssignOp::ModAssign,
43            _ => return None,
44        })
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use crate::assert_ast;
51    use crate::ast::{Ident, Int};
52    use super::*;
53
54    #[test]
55    fn test_assign_op() {
56        assert_eq!(AssignOp::from_kind(SyntaxKind::Eq), Some(AssignOp::Assign));
57        assert_eq!(AssignOp::from_kind(SyntaxKind::PlusEq), Some(AssignOp::AddAssign));
58        assert_eq!(AssignOp::from_kind(SyntaxKind::MinusEq), Some(AssignOp::SubAssign));
59        assert_eq!(AssignOp::from_kind(SyntaxKind::StarEq), Some(AssignOp::MulAssign));
60        assert_eq!(AssignOp::from_kind(SyntaxKind::SlashEq), Some(AssignOp::DivAssign));
61        assert_eq!(AssignOp::from_kind(SyntaxKind::AmpersandEq), Some(AssignOp::ModAssign));
62    }
63
64    #[test]
65    fn assignment() {
66        assert_ast!(
67            "a = 23",
68            assignment as Assignment {
69                with lhs: Ident = assignment.lhs() => {
70                    assert_eq!(lhs.get(), "a");
71                }
72                with rhs: Int = assignment.rhs() => {
73                    assert_eq!(rhs.get(), 23);
74                }
75            }
76        )
77    }
78}