Skip to main content

openpql_range_parser/ast/
term.rs

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