1extern crate proc_macro;
43
44mod jppe;
45
46use jppe::attribute::ContainerAttributes;
47use jppe::derive_enum;
48use jppe::derive_struct;
49
50use proc_macro::TokenStream;
51use quote::ToTokens;
52use virtue::prelude::*;
53use syn::{parse_macro_input, DeriveInput};
54
55
56#[proc_macro_derive(ByteDecode, attributes(jppe))]
57pub fn derive_decode(input: TokenStream) -> TokenStream {
58 derive_decode_inner(input).unwrap_or_else(|e|e.into_token_stream())
59}
60
61
62fn derive_decode_inner(input: TokenStream) -> Result<TokenStream> {
63 let parse = Parse::new(input)?;
64 let (mut generator, attributes, body) = parse.into_generator();
65 let attributes = attributes
66 .get_attribute::<ContainerAttributes>()?
67 .unwrap_or_default();
68
69 match body {
70 Body::Struct(body) => {
71 derive_struct::DeriveStruct {
72 fields: body.fields,
73 attributes,
74 lifetimes: None,
75 }.generate_decode(&mut generator)?;
76 }
77 Body::Enum(body) => {
78 derive_enum::DeriveEnum {
79 variants: body.variants,
80 attributes,
81 lifetimes: None,
82 }
83 .generate_decode(&mut generator)?;
84 }
85 }
86
87 generator.export_to_file("jppe", "Decode");
88 generator.finish()
89}
90
91
92#[proc_macro_derive(BorrowByteDecode, attributes(jppe))]
93pub fn derive_borrow_decode(input: TokenStream) -> TokenStream {
94 let input_tmp = input.clone();
95 let derive_input = parse_macro_input!(input_tmp as DeriveInput);
96 let lifetimes = derive_input.generics.to_token_stream().to_string();
97
98 derive_borrow_decode_inner(input, lifetimes).unwrap_or_else(|e|e.into_token_stream())
99}
100
101
102fn derive_borrow_decode_inner(input: TokenStream, lifetimes: String) -> Result<TokenStream> {
103 let parse = Parse::new(input)?;
104 let (mut generator, attributes, body) = parse.into_generator();
105 let attributes = attributes
106 .get_attribute::<ContainerAttributes>()?
107 .unwrap_or_default();
108
109 match body {
110 Body::Struct(body) => {
111 derive_struct::DeriveStruct {
112 fields: body.fields,
113 attributes,
114 lifetimes: if lifetimes.is_empty() { None } else {Some(lifetimes)},
115 }.generate_borrow_decode(&mut generator)?;
116 }
117 Body::Enum(body) => {
118 derive_enum::DeriveEnum {
119 variants: body.variants,
120 attributes,
121 lifetimes: if lifetimes.is_empty() { None } else {Some(lifetimes)},
122 }
123 .generate_borrow_decode(&mut generator)?;
124 }
125 }
126
127 generator.export_to_file("jppe", "Decode");
128 generator.finish()
129}
130
131
132#[proc_macro_derive(ByteEncode, attributes(jppe))]
133pub fn derive_encode(input: TokenStream) -> TokenStream {
134 derive_encode_inner(input).unwrap_or_else(|e|e.into_token_stream())
135}
136
137
138fn derive_encode_inner(input: TokenStream) -> Result<TokenStream> {
139 let parse = Parse::new(input)?;
140 let (mut generator, attributes, body) = parse.into_generator();
141 let attributes = attributes
142 .get_attribute::<ContainerAttributes>()?
143 .unwrap_or_default();
144
145 match body {
146 Body::Struct(body) => {
147 derive_struct::DeriveStruct {
148 fields: body.fields,
149 attributes,
150 lifetimes: None,
151 }.generate_encode(&mut generator)?;
152 }
153 Body::Enum(body) => {
154 derive_enum::DeriveEnum {
155 variants: body.variants,
156 attributes,
157 lifetimes: None,
158 }
159 .generate_encode(&mut generator)?;
160 }
161 }
162
163 generator.export_to_file("jppe", "Encode");
164 generator.finish()
165}
166
167
168#[proc_macro_derive(BorrowByteEncode, attributes(jppe))]
169pub fn derive_borrow_encode(input: TokenStream) -> TokenStream {
170 derive_borrow_encode_inner(input).unwrap_or_else(|e|e.into_token_stream())
171}
172
173
174fn derive_borrow_encode_inner(input: TokenStream) -> Result<TokenStream> {
175 let parse = Parse::new(input)?;
176 let (mut generator, attributes, body) = parse.into_generator();
177 let attributes = attributes
178 .get_attribute::<ContainerAttributes>()?
179 .unwrap_or_default();
180
181 match body {
182 Body::Struct(body) => {
183 derive_struct::DeriveStruct {
184 fields: body.fields,
185 attributes,
186 lifetimes: None,
187 }.generate_borrow_encode(&mut generator)?;
188 }
189 Body::Enum(body) => {
190 derive_enum::DeriveEnum {
191 variants: body.variants,
192 attributes,
193 lifetimes: None,
194 }
195 .generate_borrow_encode(&mut generator)?;
196 }
197 }
198
199 generator.export_to_file("jppe", "Encode");
200 generator.finish()
201}