checked_rs_macro_impl/
item.rs

1use syn::parse::Parse;
2
3use crate::params::Params;
4
5pub mod enum_item;
6pub mod struct_item;
7
8pub enum ClampedItem {
9    Enum(enum_item::ClampedEnumItem),
10    Struct(struct_item::ClampedStructItem),
11}
12
13impl Parse for ClampedItem {
14    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
15        if enum_item::ClampedEnumItem::has_enum_token(input.fork())? {
16            Ok(Self::Enum(input.parse()?))
17        } else {
18            Ok(Self::Struct(input.parse()?))
19        }
20    }
21}
22
23impl ClampedItem {
24    pub fn params(&self) -> syn::Result<Params> {
25        Ok(match self {
26            Self::Enum(item) => item.params()?,
27            Self::Struct(item) => item.params()?,
28        })
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use anyhow::Result;
35    use syn::parse_quote;
36
37    use crate::{item::enum_item::ClampedEnumItem, params::Params};
38
39    fn generate_enum_params(item: ClampedEnumItem) -> Result<Params> {
40        let params = item.params()?;
41
42        println!("$$$$ {:#?}", params);
43
44        Ok(params)
45    }
46
47    #[test]
48    fn test_enum_simple() -> Result<()> {
49        generate_enum_params(parse_quote! {
50            #[usize]
51            enum DoubleSentinel {
52                Zero(0),
53                Valid(..),
54                Invalid(usize::MAX),
55            }
56        })?;
57
58        Ok(())
59    }
60
61    #[test]
62    fn test_enum_non_comprehensive() -> Result<()> {
63        generate_enum_params(parse_quote! {
64            #[usize]
65            enum TenTwentyThirty {
66                Ten(10),
67                Twenty(20),
68                Thirty(30),
69            }
70        })?;
71
72        Ok(())
73    }
74
75    #[test]
76    fn test_enum_multiple_exacts() -> Result<()> {
77        generate_enum_params(parse_quote! {
78            #[usize]
79            enum SpecificValues {
80                OneTwoOrSeven(1, 2, 7),
81                AnythingElse(..),
82            }
83        })?;
84
85        Ok(())
86    }
87
88    #[test]
89    fn test_enum_multiple_ranges() -> Result<()> {
90        generate_enum_params(parse_quote! {
91            #[usize]
92            enum HundredToThousand {
93                Valid(..),
94                Invalid(..100, 1000..)
95            }
96        })?;
97
98        Ok(())
99    }
100
101    #[test]
102    fn test_enum_nested() -> Result<()> {
103        generate_enum_params(parse_quote! {
104            #[usize]
105            enum ResponseCode {
106                Success[200..300] {
107                    Okay(200),
108                    Created(201),
109                    Accepted(202),
110                    Unknown(..),
111                },
112                Redirect[300..400] {
113                    MultipleChoices(300),
114                    MovedPermanently(301),
115                    Found(302),
116                    Unknown(..),
117                },
118                Error {
119                    Client[400..500] {
120                        BadRequest(400),
121                        Unauthorized(401),
122                        PaymentRequired(402),
123                        Forbidden(403),
124                        NotFound(404),
125                        Unknown(..)
126                    },
127                    Server[500..600] {
128                        Internal(500),
129                        NotImplemented(501),
130                        BadGateway(502),
131                        ServiceUnavailable(503),
132                        GatewayTimeout(504),
133                        Unknown(..)
134                    }
135                }
136            }
137        })?;
138
139        Ok(())
140    }
141}