[fix] Split the derive into some functions
This commit is contained in:
@@ -35,53 +35,7 @@ mod derive_builder {
|
|||||||
let builder_struct_name = Ident::new(&format!("{}Builder", struct_name), Span::call_site());
|
let builder_struct_name = Ident::new(&format!("{}Builder", struct_name), Span::call_site());
|
||||||
|
|
||||||
// Use Generic type T{0..} to represent the fields
|
// Use Generic type T{0..} to represent the fields
|
||||||
let mut state = 1u32;
|
let gf = generic_fields("T", fields)?;
|
||||||
let generic_fields = fields.into_iter().scan(&mut state, |state, mut field| {
|
|
||||||
let gtype = format!("T{}", state);
|
|
||||||
**state += 1;
|
|
||||||
field.ty = syn::Type::Path(TypePath {
|
|
||||||
qself: None,
|
|
||||||
path: syn::Path {
|
|
||||||
leading_colon: None,
|
|
||||||
segments: Punctuated::from_iter(vec![PathSegment {
|
|
||||||
ident: syn::Ident::new(>ype, Span::call_site()),
|
|
||||||
arguments: PathArguments::None,
|
|
||||||
}]),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Some(field)
|
|
||||||
});
|
|
||||||
let generic_fields: Punctuated<Field, Comma> = generic_fields.collect();
|
|
||||||
let builder_generics = syn::Generics {
|
|
||||||
lt_token: Token).into(),
|
|
||||||
params: (1..state)
|
|
||||||
.map(|f| {
|
|
||||||
GenericParam::Type(TypeParam {
|
|
||||||
attrs: vec![],
|
|
||||||
ident: syn::Ident::new(&format!("T{}", f), Span::call_site()),
|
|
||||||
colon_token: None,
|
|
||||||
bounds: Punctuated::new(),
|
|
||||||
eq_token: None,
|
|
||||||
default: None,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
gt_token: Token).into(),
|
|
||||||
where_clause: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let builder_struct = syn::ItemStruct {
|
|
||||||
attrs: vec![],
|
|
||||||
vis: Visibility::Inherited,
|
|
||||||
struct_token: Token),
|
|
||||||
ident: builder_struct_name.clone(),
|
|
||||||
fields: Fields::Named(FieldsNamed {
|
|
||||||
brace_token: token::Brace::default(),
|
|
||||||
named: generic_fields,
|
|
||||||
}),
|
|
||||||
generics: builder_generics,
|
|
||||||
semi_token: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let empty_builder_type: syn::Type = syn::Type::Path(TypePath {
|
let empty_builder_type: syn::Type = syn::Type::Path(TypePath {
|
||||||
qself: None,
|
qself: None,
|
||||||
@@ -95,7 +49,7 @@ mod derive_builder {
|
|||||||
args: core::iter::repeat::<GenericArgument>(parse_quote!(
|
args: core::iter::repeat::<GenericArgument>(parse_quote!(
|
||||||
#crate_name::Empty
|
#crate_name::Empty
|
||||||
))
|
))
|
||||||
.take(state as usize - 1)
|
.take(gf.len() as usize - 1)
|
||||||
.collect(),
|
.collect(),
|
||||||
gt_token: Token),
|
gt_token: Token),
|
||||||
}),
|
}),
|
||||||
@@ -141,9 +95,70 @@ mod derive_builder {
|
|||||||
items: vec![ImplItem::Fn(empty_builder_fn)],
|
items: vec![ImplItem::Fn(empty_builder_fn)],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let bs = builder_struct()?;
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#impl_empty_builder_fn
|
#impl_empty_builder_fn
|
||||||
#builder_struct
|
#bs
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn builder_struct() -> Result<syn::ItemStruct> {
|
||||||
|
let builder_struct = syn::ItemStruct {
|
||||||
|
attrs: vec![],
|
||||||
|
vis: Visibility::Inherited,
|
||||||
|
struct_token: Token),
|
||||||
|
ident: builder_struct_name.clone(),
|
||||||
|
fields: Fields::Named(FieldsNamed {
|
||||||
|
brace_token: token::Brace::default(),
|
||||||
|
named: gf,
|
||||||
|
}),
|
||||||
|
generics: builder_generics,
|
||||||
|
semi_token: None,
|
||||||
|
};
|
||||||
|
Ok(builder_struct)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn builder_generics(ident: impl core::fmt::Display, len: usize) -> Result<syn::Generics> {
|
||||||
|
Ok(syn::Generics {
|
||||||
|
lt_token: Token).into(),
|
||||||
|
params: (1..len)
|
||||||
|
.map(|f| {
|
||||||
|
GenericParam::Type(TypeParam {
|
||||||
|
attrs: vec![],
|
||||||
|
ident: syn::Ident::new(&format!("{}{}", ident, f), Span::call_site()),
|
||||||
|
colon_token: None,
|
||||||
|
bounds: Punctuated::new(),
|
||||||
|
eq_token: None,
|
||||||
|
default: None,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
gt_token: Token).into(),
|
||||||
|
where_clause: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generic_fields(
|
||||||
|
ident: impl core::fmt::Display,
|
||||||
|
input: Punctuated<Field, Comma>,
|
||||||
|
) -> Result<Punctuated<Field, Comma>> {
|
||||||
|
Ok(input
|
||||||
|
.into_iter()
|
||||||
|
.scan(1, |state, mut field| {
|
||||||
|
let gtype = format!("{}{}", ident, state);
|
||||||
|
*state += 1;
|
||||||
|
field.ty = syn::Type::Path(TypePath {
|
||||||
|
qself: None,
|
||||||
|
path: syn::Path {
|
||||||
|
leading_colon: None,
|
||||||
|
segments: Punctuated::from_iter(vec![PathSegment {
|
||||||
|
ident: syn::Ident::new(>ype, Span::call_site()),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
}]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Some(field)
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user