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