openpql_range_parser/ast/
list.rs1use 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}