Skip to main content

bincode_derive/
lib.rs

1mod attribute;
2mod derive_enum;
3mod derive_struct;
4
5use attribute::ContainerAttributes;
6use virtue::prelude::*;
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
13fn derive_encode_inner(input: TokenStream) -> Result<TokenStream> {
14    let parse = Parse::new(input)?;
15    let (mut generator, attributes, body) = parse.into_generator();
16    let attributes = attributes
17        .get_attribute::<ContainerAttributes>()?
18        .unwrap_or_default();
19
20    match body {
21        Body::Struct(body) => {
22            derive_struct::DeriveStruct {
23                fields: body.fields,
24                attributes,
25            }
26            .generate_encode(&mut generator)?;
27        }
28        Body::Enum(body) => {
29            derive_enum::DeriveEnum {
30                variants: body.variants,
31                attributes,
32            }
33            .generate_encode(&mut generator)?;
34        }
35    }
36
37    generator.export_to_file("bincode", "Encode");
38    generator.finish()
39}
40
41#[proc_macro_derive(Decode, attributes(bincode))]
42pub fn derive_decode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
43    derive_decode_inner(input, false).unwrap_or_else(|e| e.into_token_stream())
44}
45
46fn derive_decode_inner(input: TokenStream, untrusted: bool) -> Result<TokenStream> {
47    let parse = Parse::new(input)?;
48    let (mut generator, attributes, body) = parse.into_generator();
49    let mut attributes = attributes
50        .get_attribute::<ContainerAttributes>()?
51        .unwrap_or_default();
52    attributes.untrusted = untrusted;
53
54    match body {
55        Body::Struct(body) => {
56            derive_struct::DeriveStruct {
57                fields: body.fields,
58                attributes,
59            }
60            .generate_decode(&mut generator)?;
61        }
62        Body::Enum(body) => {
63            derive_enum::DeriveEnum {
64                variants: body.variants,
65                attributes,
66            }
67            .generate_decode(&mut generator)?;
68        }
69    }
70
71    generator.export_to_file(
72        "bincode",
73        if untrusted {
74            "DecodeUntrusted"
75        } else {
76            "Decode"
77        },
78    );
79    generator.finish()
80}
81
82#[proc_macro_derive(BorrowDecode, attributes(bincode))]
83pub fn derive_borrow_decode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
84    derive_borrow_decode_inner(input, false).unwrap_or_else(|e| e.into_token_stream())
85}
86
87fn derive_borrow_decode_inner(input: TokenStream, untrusted: bool) -> Result<TokenStream> {
88    let parse = Parse::new(input)?;
89    let (mut generator, attributes, body) = parse.into_generator();
90    let mut attributes = attributes
91        .get_attribute::<ContainerAttributes>()?
92        .unwrap_or_default();
93    attributes.untrusted = untrusted;
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(
113        "bincode",
114        if untrusted {
115            "BorrowDecodeUntrusted"
116        } else {
117            "BorrowDecode"
118        },
119    );
120    generator.finish()
121}
122
123#[proc_macro_derive(DecodeUntrusted, attributes(bincode))]
124pub fn derive_decode_untrusted(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
125    derive_decode_inner(input, true).unwrap_or_else(|e| e.into_token_stream())
126}
127#[proc_macro_derive(BorrowDecodeUntrusted, attributes(bincode))]
128pub fn derive_borrow_decode_untrusted(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
129    derive_borrow_decode_inner(input, true).unwrap_or_else(|e| e.into_token_stream())
130}