openpql_range_parser/ast/
list.rs

1use super::{
2    Display, Error, LalrError, Loc, RangeCard, RankConst, SuitConst, ToString,
3};
4
5#[derive(Copy, Clone, PartialEq, Eq, Debug, Display)]
6pub enum ListElem {
7    #[display("{_0}{_1}")]
8    CC(RankConst, SuitConst),
9    #[display("{_0}")]
10    CA(RankConst),
11    #[display("{_0}")]
12    AC(SuitConst),
13}
14
15fn to_str(elems: &[ListElem]) -> String {
16    format!(
17        "[{}]",
18        elems
19            .iter()
20            .map(ToString::to_string)
21            .collect::<Vec<_>>()
22            .join(",")
23    )
24}
25
26#[derive(Clone, PartialEq, Eq, Debug, derive_more::From, Display)]
27#[display("{}", to_str(_0))]
28pub struct List(pub Vec<ListElem>);
29
30impl TryFrom<(Loc, Vec<RangeCard>, Loc)> for List {
31    type Error = LalrError<'static>;
32
33    fn try_from(
34        (l, v, r): (Loc, Vec<RangeCard>, Loc),
35    ) -> Result<Self, Self::Error> {
36        let mut inner = vec![];
37
38        for c in v {
39            match c {
40                RangeCard::CC(r, s) => {
41                    inner.push(ListElem::CC(r, s));
42                }
43                RangeCard::CA(r) => {
44                    inner.push(ListElem::CA(r));
45                }
46                RangeCard::AC(s) => {
47                    inner.push(ListElem::AC(s));
48                }
49                _ => {
50                    return Err(Error::InvalidList((l, r)).into());
51                }
52            }
53        }
54
55        Ok(Self(inner))
56    }
57}
58
59#[cfg(test)]
60#[cfg_attr(coverage_nightly, coverage(off))]
61mod tests {
62    use super::*;
63    use crate::*;
64
65    fn assert_list(src: &str, expected: &str) {
66        let list = parse_list(src).unwrap();
67
68        assert_eq!(list.to_string(), expected, "{src} != {expected}");
69    }
70
71    #[quickcheck]
72    fn test_list(c: RangeCard) {
73        let src = format!("[{c}]");
74        let res = parse_list(&src);
75
76        let is_err = match c {
77            RangeCard::CC(_, _) | RangeCard::CA(_) | RangeCard::AC(_) => false,
78            RangeCard::CV(_, _)
79            | RangeCard::VC(_, _)
80            | RangeCard::VV(_, _)
81            | RangeCard::VA(_)
82            | RangeCard::AV(_)
83            | RangeCard::AA => true,
84        };
85
86        if is_err {
87            assert_eq!(res, Err(Error::InvalidList((0, src.len())).into()));
88        } else {
89            assert_eq!(res, Ok((0, vec![c], 0).try_into().unwrap()));
90        }
91    }
92
93    #[test]
94    fn test_list_ok() {
95        assert_list("[A, s]", "[A,s]");
96    }
97
98    #[test]
99    fn test_list_error() {
100        assert_eq!(parse_list("[B] "), Err(Error::InvalidList((0, 3)).into()));
101        assert_eq!(parse_list("[Bs]"), Err(Error::InvalidList((0, 4)).into()));
102        assert_eq!(parse_list("[*w]"), Err(Error::InvalidList((0, 4)).into()));
103        assert_eq!(parse_list("[Aw]"), Err(Error::InvalidList((0, 4)).into()));
104        assert_eq!(parse_list("[Bw]"), Err(Error::InvalidList((0, 4)).into()));
105        assert_eq!(parse_list("[*] "), Err(Error::InvalidList((0, 3)).into()));
106    }
107}