espr/parser/entity/
unique.rs1use super::attribute::*;
2use crate::{
3 ast::*,
4 parser::{combinator::*, identifier::*},
5};
6
7pub 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
16pub 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}