git.delta.rocks / unique-network / refs/commits / 03a2300a9d25

difftreelog

refactor(versioning) remove multiversion

Yaroslav Bolyukin2022-04-07parent: #d837c88.patch.diff
in: master

1 file changed

modifiedcrates/struct-versioning/src/lib.rsdiffbeforeafterboth
3use syn::{3use syn::{
4 parse::{Parse, ParseStream},4 parse::{Parse, ParseStream},
5 Token, LitInt, parse_macro_input, ItemStruct, Error, Fields, Result, Field,5 Token, LitInt, parse_macro_input, ItemStruct, Error, Fields, Result, Field, Expr,
6 punctuated::Punctuated, Expr, parenthesized,6 parenthesized,
7};7};
8use quote::quote;8use quote::quote;
99
18 current_version: u32,18 current_version: u32,
19 first_version: u32,19 first_version: u32,
20 upper: bool,20 upper: bool,
21 versions: bool,
22}21}
2322
24/// #[versioned(version = 2)]23/// #[versioned(version = 2)]
27 let mut current_version = None::<u32>;26 let mut current_version = None::<u32>;
28 let mut first_version = None::<u32>;27 let mut first_version = None::<u32>;
29 let mut upper = false;28 let mut upper = false;
30 let mut versions = false;
3129
32 loop {30 loop {
33 if input.is_empty() {31 if input.is_empty() {
53 } else if lookahead.peek(kw::upper) {51 } else if lookahead.peek(kw::upper) {
54 input.parse::<kw::upper>()?;52 input.parse::<kw::upper>()?;
55 upper = true;53 upper = true;
56 } else if lookahead.peek(kw::versions) {54 } else {
57 input.parse::<kw::version>()?;
58 versions = true;
59 } else {
60 return Err(lookahead.error())55 return Err(lookahead.error());
61 }56 }
6257
63 if input.is_empty() {58 if input.is_empty() {
64 break59 break;
65 } else if input.peek(Token![,]) {60 } else if input.peek(Token![,]) {
66 input.parse::<Token![,]>()?;61 input.parse::<Token![,]>()?;
67 continue62 continue;
68 } else {63 } else {
69 return Err(input.error("unexpected token"))64 return Err(input.error("unexpected token"));
70 }65 }
71 }66 }
72 let first_version = first_version.unwrap_or(1);67 let first_version = first_version.unwrap_or(1);
73 let current_version = current_version.unwrap_or(first_version);68 let current_version = current_version.unwrap_or(first_version);
7469
75 if current_version == 0 || first_version == 0 || first_version > current_version {70 if current_version == 0 || first_version == 0 || first_version > current_version {
76 return Err(Error::new(input.span(), "1 <= first_version <= version"))71 return Err(Error::new(input.span(), "1 <= first_version <= version"));
77 }72 }
7873
79 Ok(Self {74 Ok(Self {
80 current_version,75 current_version,
81 first_version,76 first_version,
82 upper,77 upper,
83 versions,
84 })78 })
85 }79 }
86}80}
225 quote! {#ty}
226 ))
223 }227 }
224 _ => {},228 _ => {}
225 }229 }
226 }230 }
227 }231 }
236 .filter(|(v, _)| !v.exists_on(version - 1) && v.exists_on(version))242 .filter(|(v, _)| !v.exists_on(version - 1) && v.exists_on(version))
237 .map(|(v, f)| {243 .map(|(v, f)| {
238 let name = f.ident.as_ref().unwrap();244 let name = f.ident.as_ref().unwrap();
239 let value = v.upper.clone().unwrap_or_else(|| Expr::Verbatim(Error::new_spanned(f, "missing upper declaration").to_compile_error()));245 let value = v.upper.clone().unwrap_or_else(|| {
246 Expr::Verbatim(
247 Error::new_spanned(f, "missing upper declaration").to_compile_error(),
248 )
249 });
240 quote! { #name: #value }250 quote! { #name: #value }
241 });251 });
242 let passed_fields = fields.iter()252 let passed_fields = fields
275 let ident = &input.ident;288 let ident = &input.ident;
276 let last_version = format_ident!("{}Version{}", input.ident, attr.current_version);289 let last_version = format_ident!("{}Version{}", input.ident, attr.current_version);
277
278 let versions = if attr.versions {
279 let name = format_ident!("{}Versions", input.ident);
280 let versions = (attr.first_version..=attr.current_version).map(|v| {
281 let var_name = format_ident!("V{}", v);
282 let var_type = format_ident!("{}Version{}", input.ident, v);
283 quote! {
284 #var_name(#var_type),
285 }
286 });
287 let versions = (attr.first_version..=attr.current_version).map(|this_version| {
288 let var_name = format_ident!("V{}", this_version);
289 let stages = (this_version+1..=attr.current_version).map(|v| {
290 let var_type = format_ident!("{}Version{}", input.ident, v);
291 quote! {
292 let v = #var_type::from(v);
293 }
294 });
295 quote! {
296 #var_name(v) => {
297 #(#stages)*
298 v
299 }
300 }
301 }).collect::<Vec<_>>();
302 quote! {
303 #vis enum #name {
304 #(#versions)*
305 }
306 impl struct_versioning::Versions for #name {
307 type Last = #last_version;
308 fn up(self) -> Self::Last {
309 match self {
310 #(#versions)*
311 }
312 }
313 }
314 }
315 } else {quote!{}};
316290
317 quote! {291 quote! {
318 #(#out)*292 #(#out)*
319293
320 #vis type #ident #ty_generics = #last_version #ty_generics;294 #vis type #ident #ty_generics = #last_version #ty_generics;
321
322 #versions
323 }295 }
324 .into()296 .into()
325}297}