espr/parser/entity/
domain.rs

1use super::super::{combinator::*, expression::*, identifier::*};
2use crate::ast::*;
3
4/// 338 where_clause = WHERE [domain_rule] `;` { [domain_rule] `;` } .
5pub fn where_clause(input: &str) -> ParseResult<WhereClause> {
6    tuple((tag("WHERE"), many0(tuple((domain_rule, char(';'))))))
7        .map(|(_where, rules)| {
8            let rules = rules.into_iter().map(|(rule, _semicolon)| rule).collect();
9            WhereClause { rules }
10        })
11        .parse(input)
12}
13
14/// 202 domain_rule = \[ [rule_label_id] `:` \] [expression] .
15pub fn domain_rule(input: &str) -> ParseResult<DomainRule> {
16    tuple((opt(tuple((rule_label_id, char(':')))), expression))
17        .map(|(opt, expr)| {
18            let label = opt.map(|(label, _colon)| label);
19            DomainRule { label, expr }
20        })
21        .parse(input)
22}
23
24#[cfg(test)]
25mod tests {
26    use nom::Finish;
27
28    #[test]
29    fn domain_rule() {
30        let (residual, (rule, _remarks)) =
31            super::domain_rule("notnegative : a > 0").finish().unwrap();
32        assert_eq!(residual, "");
33        assert_eq!(rule.label, Some("notnegative".to_string()));
34    }
35
36    #[test]
37    fn where_clause() {
38        let (residual, (w, _remarks)) = super::where_clause(
39            r#"
40            WHERE
41                notnegative : SELF > 0;
42            "#
43            .trim(),
44        )
45        .finish()
46        .unwrap();
47        assert_eq!(residual, "");
48        assert_eq!(w.rules.len(), 1);
49        assert_eq!(w.rules[0].label, Some("notnegative".to_string()));
50    }
51
52    #[test]
53    fn where_clause_complex() {
54        let (residual, (w, _remarks)) = super::where_clause(
55            r#"
56            WHERE
57                wr1: (1 <= SELF) AND (SELF <= 12);
58            "#
59            .trim(),
60        )
61        .finish()
62        .unwrap();
63        assert_eq!(residual, "");
64        assert_eq!(w.rules.len(), 1);
65        assert_eq!(w.rules[0].label, Some("wr1".to_string()));
66    }
67
68    #[test]
69    fn where_clause3() {
70        let (residual, (w, _remarks)) = super::where_clause(
71            r#"
72            WHERE
73                wr1 : VALUE_UNIQUE(s);
74            "#
75            .trim(),
76        )
77        .finish()
78        .unwrap();
79        assert_eq!(residual, "");
80        dbg!(w);
81    }
82}