kago_macros/
lib.rs

1//! Kago-Core (籠コア)
2//!
3//! Kago で用いられる実装のマクロを提供する。
4
5#![warn(
6    missing_docs,
7    rustdoc::missing_crate_level_docs,
8    unused_results,
9    clippy::complexity,
10    clippy::perf,
11    clippy::style
12)]
13#![deny(clippy::correctness, clippy::suspicious)]
14
15mod bit_ops;
16mod bounded;
17mod core;
18mod from;
19mod num;
20mod num_cast;
21mod num_ops;
22mod ougi;
23mod prim_int;
24mod sign;
25
26use proc_macro::TokenStream;
27use proc_macro2::Span;
28use quote::quote;
29use std::ops::RangeInclusive;
30use syn::Ident;
31
32/// 実装
33#[proc_macro]
34pub fn limited_bits(tokens: TokenStream) -> TokenStream {
35    limited_bits_impl(tokens.into(), 1..=128).into()
36}
37
38/// 互いの変換
39#[proc_macro]
40pub fn impl_from(_: TokenStream) -> TokenStream {
41    let range = 1..=128;
42    let from_impl = from::impl_from(&range);
43    from_impl.into()
44}
45
46/// Ougi
47#[proc_macro]
48pub fn impl_ougi(_: TokenStream) -> TokenStream {
49    let range = 1..=128;
50    let impls = ougi::impl_ougi(&range);
51    impls.into()
52}
53
54fn limited_bits_impl(
55    _: proc_macro2::TokenStream,
56    range: RangeInclusive<u32>,
57) -> proc_macro2::TokenStream {
58    let mut impls = Vec::new();
59    for n in range.clone() {
60        for is_signed in [false, true].iter() {
61            let flag_name = core::feature_name(n, *is_signed);
62            let module_name = Ident::new(format!("bit_{}", flag_name).as_str(), Span::call_site());
63            let struct_name = core::struct_name(n, *is_signed);
64            let ty = core::inner_type(n, *is_signed);
65            let shift = core::shift(n);
66            let masking = core::masking(&shift);
67            let struct_impl = core::impl_struct(&struct_name, &ty, &shift);
68            let debug_impl = core::impl_debug(&struct_name, &shift);
69            let binary_impl = core::impl_binary(n, &struct_name, &shift);
70            let add_impl = num_ops::impl_add(&struct_name);
71            let sub_impl = num_ops::impl_sub(&struct_name);
72            let mul_impl = num_ops::impl_mul(&struct_name, &shift);
73            let div_impl = num_ops::impl_div(&struct_name, &shift);
74            let rem_impl = num_ops::impl_rem(&struct_name);
75            let checked_add_impl = num_ops::impl_checked_add(&struct_name);
76            let checked_sub_impl = num_ops::impl_checked_sub(&struct_name);
77            let checked_mul_impl = num_ops::impl_checked_mul(&struct_name, &ty, &shift);
78            let checked_div_impl = num_ops::impl_checked_div(&struct_name, &ty, &shift);
79            let checked_rem_impl = num_ops::impl_checked_rem(&struct_name, &ty);
80            let saturating_impl = num_ops::impl_saturating(&struct_name, &ty, &masking);
81            let zero_impl = num::impl_zero(&struct_name);
82            let one_impl = num::impl_one(&struct_name);
83            let num_impl = num::impl_num(&struct_name, &ty);
84            let to_primitive_impl = num_cast::impl_to_primitive(&struct_name, &ty, &shift);
85            let wrapping_add_impl = num_ops::impl_wrapping_add(&struct_name);
86            let wrapping_sub_impl = num_ops::impl_wrapping_sub(&struct_name);
87            let num_cast_impl = num_cast::impl_num_cast(&struct_name, &ty, &shift);
88            let bounded_impl = bounded::impl_bounded(&struct_name, &ty, &shift);
89            let not_impl = bit_ops::impl_not(&struct_name, &masking);
90            let bitand_impl = bit_ops::impl_bitand(&struct_name, &masking);
91            let bitor_impl = bit_ops::impl_bitor(&struct_name, &masking);
92            let bitxor_impl = bit_ops::impl_bitxor(&struct_name, &masking);
93            let shl_impl = bit_ops::impl_shl(&struct_name);
94            let shr_impl = bit_ops::impl_shr(&struct_name, &masking);
95            let prim_int_impl = prim_int::impl_prim_int(&struct_name, &ty, &shift, &masking);
96            let sign_impl = sign::impl_sign(&struct_name, *is_signed);
97            impls.push(quote! {
98                #[cfg(feature = #flag_name)]
99                pub use #module_name::#struct_name;
100
101                #[cfg(feature = #flag_name)]
102                mod #module_name {
103                    #struct_impl
104                    #debug_impl
105                    #binary_impl
106                    #add_impl
107                    #checked_add_impl
108                    #wrapping_add_impl
109                    #sub_impl
110                    #checked_sub_impl
111                    #wrapping_sub_impl
112                    #mul_impl
113                    #checked_mul_impl
114                    #div_impl
115                    #checked_div_impl
116                    #rem_impl
117                    #checked_rem_impl
118                    #saturating_impl
119                    #zero_impl
120                    #one_impl
121                    #num_impl
122                    #to_primitive_impl
123                    #num_cast_impl
124                    #bounded_impl
125                    #not_impl
126                    #bitand_impl
127                    #bitor_impl
128                    #bitxor_impl
129                    #shl_impl
130                    #shr_impl
131                    #prim_int_impl
132                    #sign_impl
133                }
134            });
135        }
136    }
137    quote! {
138        #(#impls)*
139    }
140}