catchr_core/
section_keyword.rs

1use proc_macro2::Span;
2use syn::parse::{self, Parse, ParseStream};
3
4mod kw {
5    syn::custom_keyword!(when);
6    syn::custom_keyword!(then);
7    syn::custom_keyword!(given);
8    syn::custom_keyword!(case);
9    syn::custom_keyword!(section);
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum SectionKeyword {
14    When,
15    Then,
16    Given,
17    Case,
18    Section,
19}
20
21impl SectionKeyword {
22    pub fn to_name(&self) -> String {
23        match self {
24            Self::When => "when".to_string(),
25            Self::Then => "then".to_string(),
26            Self::Given => "given".to_string(),
27            Self::Case => "case".to_string(),
28            Self::Section => "section".to_string(),
29        }
30    }
31}
32
33impl SectionKeyword {
34    pub fn peek(i: ParseStream) -> bool {
35        let lk = i.lookahead1();
36
37        let mut test = false;
38
39        test |= lk.peek(kw::when);
40        test |= lk.peek(kw::given);
41        test |= lk.peek(kw::section);
42        test |= lk.peek(kw::then);
43        test |= lk.peek(kw::case);
44
45        test
46    }
47}
48
49impl Parse for SectionKeyword {
50    fn parse(input: ParseStream) -> parse::Result<Self> {
51        let lk = input.lookahead1();
52
53        if lk.peek(kw::when) {
54            input.parse::<kw::when>()?;
55
56            Ok(Self::When)
57        } else if lk.peek(kw::then) {
58            input.parse::<kw::then>()?;
59
60            Ok(Self::Then)
61        } else if lk.peek(kw::given) {
62            input.parse::<kw::given>()?;
63
64            Ok(Self::Given)
65        } else if lk.peek(kw::case) {
66            input.parse::<kw::case>()?;
67
68            Ok(Self::Case)
69        } else if lk.peek(kw::section) {
70            input.parse::<kw::section>()?;
71
72            Ok(Self::Section)
73        } else {
74            Err(parse::Error::new(
75                Span::call_site(),
76                "Invalid section keyword",
77            ))
78        }
79    }
80}
81
82#[cfg(test)]
83#[cfg(test)]
84mod tests {
85    use test_case::test_case;
86
87    use super::*;
88
89    #[test_case("when"      => SectionKeyword::When     ; "when")]
90    #[test_case("given"     => SectionKeyword::Given    ; "given")]
91    #[test_case("section"   => SectionKeyword::Section  ; "section")]
92    #[test_case("then"      => SectionKeyword::Then     ; "then")]
93    #[test_case("case"      => SectionKeyword::Case     ; "case")]
94    fn parse(s: &str) -> SectionKeyword {
95        syn::parse_str(s).unwrap()
96    }
97
98    #[test_case(SectionKeyword::When,    "when"     ; "when")]
99    #[test_case(SectionKeyword::Given,   "given"    ; "given")]
100    #[test_case(SectionKeyword::Section, "section"  ; "section")]
101    #[test_case(SectionKeyword::Then,    "then"     ; "then")]
102    #[test_case(SectionKeyword::Case,    "case"     ; "case")]
103    fn to_name(kw: SectionKeyword, exp: &str) {
104        assert_eq!(&kw.to_name(), exp);
105    }
106}