Skip to main content

openpql_range_parser/ast/
term.rs

1use super::{Display, From, List, RangeCard, Span, ToString};
2
3/// Product of cards, lists, and spans forming a range term.
4#[derive(Clone, PartialEq, Eq, Debug, derive_more::From, Display)]
5#[display("{}", to_str(_0))]
6pub struct Term(pub Vec<TermElem>);
7
8impl From<Span> for Term {
9    fn from(s: Span) -> Self {
10        Self(vec![TermElem::Span(s)])
11    }
12}
13
14/// Single element within a [`Term`].
15#[derive(Clone, PartialEq, Eq, Debug, Display)]
16pub enum TermElem {
17    /// Single range card.
18    #[display("{_0}")]
19    Card(RangeCard),
20    /// Bracketed list of alternatives.
21    #[display("{_0}")]
22    List(List),
23    /// Rank span.
24    #[display("{_0}")]
25    Span(Span),
26}
27
28fn to_str(elems: &[TermElem]) -> String {
29    elems.iter().map(ToString::to_string).collect::<String>()
30}
31
32#[cfg(test)]
33#[cfg_attr(coverage_nightly, coverage(off))]
34mod tests {
35    use crate::*;
36
37    fn assert_term(src: &str, expected: &str) {
38        let list = parse_term(src).unwrap();
39
40        assert_eq!(list.to_string(), expected, "{src} != {expected}");
41    }
42
43    #[test]
44    fn test_card() {
45        assert_term("AsA", "AsA");
46    }
47
48    #[test]
49    fn test_list() {
50        assert_term("[A,K]", "[A,K]");
51        assert_term("[A]", "[A]");
52        assert_term("[A,]", "[A]");
53    }
54
55    #[test]
56    fn test_span() {
57        assert_term("[A-]", "A-");
58        assert_term("A-", "A-");
59    }
60
61    #[test]
62    fn test_term() {
63        assert_term("R[A,K]", "R[A,K]");
64    }
65
66    #[test]
67    fn test_span_error_invalid() {
68        assert_err(parse_term("A[A]+ "), Error::InvalidSpan((0, 5)));
69        assert_err(parse_term("A[A-]-"), Error::InvalidSpan((0, 6)));
70        assert_err(parse_term("[A]-A "), Error::InvalidSpan((0, 5)));
71        assert_err(parse_term("A-[A] "), Error::InvalidSpan((0, 5)));
72    }
73}