pomsky_syntax/exprs/
stmt.rs

1use crate::Span;
2
3use super::{Rule, test::Test};
4
5#[derive(Debug, Clone)]
6#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
7pub struct StmtExpr {
8    pub stmt: Stmt,
9    pub rule: Rule,
10    pub span: Span,
11}
12
13#[derive(Debug, Clone)]
14#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
15pub enum Stmt {
16    Enable(BooleanSetting, Span),
17    Disable(BooleanSetting, Span),
18    Let(Let),
19    Test(Test),
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
24pub enum BooleanSetting {
25    Lazy,
26    Unicode,
27}
28
29impl BooleanSetting {
30    #[cfg(feature = "dbg")]
31    fn pretty_print(&self, buf: &mut crate::PrettyPrinter) {
32        match self {
33            BooleanSetting::Lazy => buf.write("lazy"),
34            BooleanSetting::Unicode => buf.write("unicode"),
35        }
36    }
37}
38
39#[derive(Debug, Clone)]
40pub struct Let {
41    pub name: String,
42    pub rule: Rule,
43    pub name_span: Span,
44}
45
46impl Let {
47    pub fn new(name: &str, rule: Rule, name_span: Span) -> Self {
48        Self { name: name.to_string(), rule, name_span }
49    }
50
51    pub fn name(&self) -> &str {
52        &self.name
53    }
54}
55
56#[cfg(feature = "arbitrary")]
57impl arbitrary::Arbitrary<'_> for Let {
58    fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
59        let name = super::arbitrary::Ident::create(u)?;
60        Ok(Let { name, rule: Rule::arbitrary(u)?, name_span: Span::arbitrary(u)? })
61    }
62
63    fn size_hint(depth: usize) -> (usize, Option<usize>) {
64        Self::try_size_hint(depth).unwrap_or_default()
65    }
66
67    fn try_size_hint(
68        depth: usize,
69    ) -> arbitrary::Result<(usize, Option<usize>), arbitrary::MaxRecursionReached> {
70        use arbitrary::size_hint::*;
71        try_recursion_guard(depth, |depth| {
72            Ok(and(super::arbitrary::Ident::size_hint(depth), Rule::try_size_hint(depth)?))
73        })
74    }
75}
76
77impl StmtExpr {
78    pub fn new(stmt: Stmt, rule: Rule, span: Span) -> Self {
79        Self { stmt, rule, span }
80    }
81
82    #[cfg(feature = "dbg")]
83    pub(super) fn pretty_print(&self, buf: &mut crate::PrettyPrinter) {
84        match &self.stmt {
85            Stmt::Enable(setting, _) | Stmt::Disable(setting, _) => {
86                buf.write(if matches!(&self.stmt, Stmt::Enable(..)) {
87                    "enable "
88                } else {
89                    "disable "
90                });
91                setting.pretty_print(buf);
92                buf.write(";\n");
93                self.rule.pretty_print(buf, false);
94            }
95            Stmt::Let(r#let) => {
96                buf.push_str("let ");
97                buf.write(&r#let.name);
98                buf.push_str(" = ");
99                r#let.rule.pretty_print(buf, true);
100                buf.write(";\n");
101                self.rule.pretty_print(buf, false);
102            }
103            Stmt::Test(test) => {
104                buf.push_str("test ");
105                buf.start_indentation("{");
106
107                let len = test.cases.len();
108                for (i, test_case) in test.cases.iter().enumerate() {
109                    test_case.pretty_print(buf);
110                    if i < len - 1 {
111                        buf.write("\n");
112                    }
113                }
114                buf.end_indentation("}");
115                buf.write("\n");
116                self.rule.pretty_print(buf, false);
117            }
118        }
119    }
120}