bincode_derive_next/
lib.rs

1mod attribute;
2mod derive_enum;
3mod derive_struct;
4
5use attribute::ContainerAttributes;
6use virtue::prelude::{AttributeAccess, Body, Parse, Result, TokenStream};
7
8#[proc_macro_derive(Encode, attributes(bincode))]
9pub fn derive_encode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
10    derive_encode_inner(input).unwrap_or_else(|e| e.into_token_stream())
11}
12
13/// # Errors
14///
15/// Returns an error if the input cannot be parsed or if the code generation fails.
16fn derive_encode_inner(input: TokenStream) -> Result<TokenStream> {
17    let parse = Parse::new(input)?;
18    let (mut generator, attributes, body) = parse.into_generator();
19    let attributes = attributes
20        .get_attribute::<ContainerAttributes>()?
21        .unwrap_or_default();
22
23    match body {
24        Body::Struct(body) => {
25            derive_struct::DeriveStruct {
26                fields: body.fields,
27                attributes,
28            }
29            .generate_encode(&mut generator)?;
30        }
31        Body::Enum(body) => {
32            derive_enum::DeriveEnum {
33                variants: body.variants,
34                attributes,
35            }
36            .generate_encode(&mut generator)?;
37        }
38    }
39
40    generator.export_to_file("bincode_next", "Encode");
41    generator.finish()
42}
43
44#[proc_macro_derive(Decode, attributes(bincode))]
45pub fn derive_decode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
46    derive_decode_inner(input).unwrap_or_else(|e| e.into_token_stream())
47}
48
49/// # Errors
50///
51/// Returns an error if the input cannot be parsed or if the code generation fails.
52fn derive_decode_inner(input: TokenStream) -> Result<TokenStream> {
53    let parse = Parse::new(input)?;
54    let (mut generator, attributes, body) = parse.into_generator();
55    let attributes = attributes
56        .get_attribute::<ContainerAttributes>()?
57        .unwrap_or_default();
58
59    match body {
60        Body::Struct(body) => {
61            derive_struct::DeriveStruct {
62                fields: body.fields,
63                attributes,
64            }
65            .generate_decode(&mut generator)?;
66        }
67        Body::Enum(body) => {
68            derive_enum::DeriveEnum {
69                variants: body.variants,
70                attributes,
71            }
72            .generate_decode(&mut generator)?;
73        }
74    }
75
76    generator.export_to_file("bincode_next", "Decode");
77    generator.finish()
78}
79
80#[proc_macro_derive(BorrowDecode, attributes(bincode))]
81pub fn derive_borrow_decode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
82    derive_borrow_decode_inner(input).unwrap_or_else(|e| e.into_token_stream())
83}
84
85/// # Errors
86///
87/// Returns an error if the input cannot be parsed or if the code generation fails.
88fn derive_borrow_decode_inner(input: TokenStream) -> Result<TokenStream> {
89    let parse = Parse::new(input)?;
90    let (mut generator, attributes, body) = parse.into_generator();
91    let attributes = attributes
92        .get_attribute::<ContainerAttributes>()?
93        .unwrap_or_default();
94
95    match body {
96        Body::Struct(body) => {
97            derive_struct::DeriveStruct {
98                fields: body.fields,
99                attributes,
100            }
101            .generate_borrow_decode(&mut generator)?;
102        }
103        Body::Enum(body) => {
104            derive_enum::DeriveEnum {
105                variants: body.variants,
106                attributes,
107            }
108            .generate_borrow_decode(&mut generator)?;
109        }
110    }
111
112    generator.export_to_file("bincode_next", "BorrowDecode");
113    generator.finish()
114}