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)]
7pub enum ListElem {
8 #[display("{_0}{_1}")]
10 CC(RankConst, SuitConst),
11 #[display("{_0}")]
13 CA(RankConst),
14 #[display("{_0}")]
16 AC(SuitConst),
17}
18
19fn to_str(elems: &[ListElem]) -> String {
20 format!(
21 "[{}]",
22 elems
23 .iter()
24 .map(ToString::to_string)
25 .collect::<Vec<_>>()
26 .join(",")
27 )
28}
29
30#[derive(Clone, PartialEq, Eq, Debug, derive_more::From, Display)]
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}