indiscriminant_impl/
lib.rs1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3
4use syn::{parse_macro_input, Data, DeriveInput, Expr, Lit};
5
6use indiscriminant_lib::indiscriminant_bits;
7use indiscriminant_lib::indiscriminant_byte_str;
8use indiscriminant_lib::indiscriminant_str;
9
10#[proc_macro_attribute]
11pub fn indiscriminant_str(args: TokenStream, input: TokenStream) -> TokenStream {
12 TokenStream::from(indiscriminant_str::indiscriminant_str(
13 TokenStream2::from(args),
14 TokenStream2::from(input),
15 ))
16}
17
18#[proc_macro_attribute]
19pub fn indiscriminant_byte_str(args: TokenStream, input: TokenStream) -> TokenStream {
20 TokenStream::from(indiscriminant_byte_str::indiscriminant_byte_str(
21 TokenStream2::from(args),
22 TokenStream2::from(input),
23 ))
24}
25
26#[proc_macro_attribute]
27pub fn indiscriminant_bits(args: TokenStream, input: TokenStream) -> TokenStream {
28 TokenStream::from(indiscriminant_bits::indiscriminant_bits(
29 TokenStream2::from(args),
30 TokenStream2::from(input),
31 ))
32}
33
34#[proc_macro_attribute]
35pub fn indiscriminant(args: TokenStream, input: TokenStream) -> TokenStream {
36 let input_cloned = input.clone();
37 let input_cloned = parse_macro_input!(input_cloned as DeriveInput);
39 let data = match input_cloned.data {
40 Data::Enum(data) => data,
41 _ => panic!("Attribute not applied to enum!"),
42 };
43 assert!(data.variants.len() > 0, "Enum is empty of any variants!");
44
45 let v = data.variants.iter().next().unwrap();
46
47 let literal = match &v.discriminant {
48 Some((_, Expr::Lit(literal))) => literal,
49 _ => panic!("Literal not found for first discriminant!"),
50 };
51
52 let args = TokenStream2::from(args);
53 let input = TokenStream2::from(input);
54 let result = match &literal.lit {
55 Lit::Str(_) => indiscriminant_str::indiscriminant_str(args, input),
56 Lit::ByteStr(_) => indiscriminant_byte_str::indiscriminant_byte_str(args, input),
57 Lit::Byte(_) | Lit::Int(_) => indiscriminant_bits::indiscriminant_bits(args, input),
58 _ => panic!("First literal is not string, byte-string, or integer!"),
59 };
60 TokenStream::from(result)
61}