espr/parser/entity/
unique.rs

1use super::attribute::*;
2use crate::{
3    ast::*,
4    parser::{combinator::*, identifier::*},
5};
6
7/// 333 unique_clause = UNIQUE [unique_rule] `;` { [unique_rule] `;` } .
8pub fn unique_clause(input: &str) -> ParseResult<UniqueClause> {
9    tuple((tag("UNIQUE"), many0(tuple((unique_rule, char(';'))))))
10        .map(|(_unique, seq)| UniqueClause {
11            rules: seq.into_iter().map(|(rule, _semicolon)| rule).collect(),
12        })
13        .parse(input)
14}
15
16/// 334 unique_rule = \[ [rule_label_id] `:` \] [referenced_attribute] { `,` [referenced_attribute] } .
17pub fn unique_rule(input: &str) -> ParseResult<UniqueRule> {
18    tuple((
19        opt(tuple((rule_label_id, char(':')))),
20        comma_separated(referenced_attribute),
21    ))
22    .map(|(opt_id, attributes)| UniqueRule {
23        name: opt_id.map(|(name, _colon)| name),
24        attributes,
25    })
26    .parse(input)
27}
28
29#[cfg(test)]
30mod tests {
31    use nom::Finish;
32
33    #[test]
34    fn unique_clause() {
35        let (residual, (c, _remarks)) = super::unique_clause(
36            r#"
37            UNIQUE
38              ur1 : revision_identifier, drawing_identifier;
39            "#
40            .trim(),
41        )
42        .finish()
43        .unwrap();
44        assert_eq!(residual, "");
45        assert_eq!(c.rules.len(), 1);
46    }
47
48    #[test]
49    fn unique_clause_termination() {
50        let (residual, (c, _remarks)) = super::unique_clause(
51            r#"
52            UNIQUE
53              ur1 : revision_identifier1, drawing_identifier1;
54              ur2 : revision_identifier2, drawing_identifier2;
55            END_ENTITY;
56            "#
57            .trim(),
58        )
59        .finish()
60        .unwrap();
61        assert_eq!(residual, "END_ENTITY;");
62        assert_eq!(c.rules.len(), 2);
63    }
64}