checked_rs_macro_impl/
lib.rs1use proc_macro2::TokenStream;
8
9pub mod common_impl;
10pub mod enum_impl;
11pub mod hard_impl;
12pub mod soft_impl;
13
14pub mod item;
15pub mod params;
16mod range_seq;
17
18use item::ClampedItem;
19use params::NumberValueRange;
20
21pub fn clamped(item: ClampedItem) -> TokenStream {
22 let params = match item.params() {
23 Ok(params) => params,
24 Err(err) => return err.to_compile_error(),
25 };
26
27 match item {
28 ClampedItem::Enum(item) => match enum_impl::define_mod(¶ms, &item.variants) {
29 Ok(ts) => ts,
30 Err(err) => err.to_compile_error(),
31 },
32 ClampedItem::Struct(item) => {
33 let ranges = item
34 .field
35 .ranges
36 .iter()
37 .map(|range| NumberValueRange::from_arg_range(range.clone(), params.integer))
38 .collect::<syn::Result<Vec<_>>>();
39
40 let ranges = match ranges {
41 Ok(ranges) => ranges,
42 Err(err) => return err.to_compile_error(),
43 };
44
45 match item.as_soft_or_hard {
46 None => match soft_impl::define_mod(¶ms, &ranges) {
47 Ok(ts) => ts,
48 Err(err) => err.to_compile_error(),
49 },
50 Some(params::AsSoftOrHard::Soft { .. }) => {
51 match soft_impl::define_mod(¶ms, &ranges) {
52 Ok(ts) => ts,
53 Err(err) => err.to_compile_error(),
54 }
55 }
56 Some(params::AsSoftOrHard::Hard { .. }) => {
57 match hard_impl::define_mod(¶ms, &ranges) {
58 Ok(ts) => ts,
59 Err(err) => err.to_compile_error(),
60 }
61 }
62 }
63 }
64 }
65}
66
67#[cfg(test)]
68macro_rules! snapshot {
69 ($ty:ty => { $($tt:tt)* }) => {{
70 let ts: $ty = match syn::parse2(quote::quote!($($tt)*)) {
71 Ok(ts) => ts,
72 Err(err) => panic!("Failed to parse as `{}`: {}", stringify!($ty), err),
73 };
74
75 insta::assert_snapshot!(&ts.to_token_stream().to_string());
76 }};
77 ($ty:ty => { $($tt:tt)* } => Formatted) => {{
78 let ts: $ty = match syn::parse2(quote::quote!($($tt)*)) {
79 Ok(ts) => ts,
80 Err(err) => panic!("Failed to parse as `{}`: {}", stringify!($ty), err),
81 };
82
83 insta::assert_snapshot!(prettyplease::unparse(
84 &syn::parse_file(&ts.to_token_stream().to_string()).unwrap()
85 ));
86 }};
87}
88
89#[cfg(test)]
90pub(crate) use snapshot;
91
92#[cfg(test)]
93macro_rules! assert_parse {
94 ($ty:ty => { $($tt:tt)* }) => {{
95 match syn::parse2::<$ty>(quote::quote!($($tt)*)) {
96 Ok(..) => { },
97 Err(err) => panic!("Failed to parse: {}", err),
98 };
99 }};
100
101 ($ty:ty => { $($tt:tt)* } => !) => {{
102 match syn::parse2::<$ty>(quote::quote!($($tt)*)) {
103 Ok(..) => panic!("Expected to fail parsing"),
104 Err(..) => { }
105 }
106 }};
107
108 ($ty:ty => { $($tt:tt)* } => { $($exp:tt)* }) => {{
109 let x = match syn::parse2::<$ty>(quote::quote!($($tt)*)) {
110 Ok(x) => x,
111 Err(err) => panic!("Failed to parse: {}", err),
112 };
113
114 if !matches!(x, $($exp)*) {
115 panic!("Expected {:?}, got {:?}", quote::quote!($($exp)*), quote::quote!(x));
116 }
117 }};
118}
119
120#[cfg(test)]
121pub(crate) use assert_parse;