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}