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