macro_rules! wrap_with_args {
(
$wrap:ident => $args:ident;
$vis:vis struct $name:ident$(<
$($generic_type:ident : $first_generic_type_bound:tt $(+ $generic_type_bound:tt)*),+ $(,)?
>)? {
$($field_vis:vis $field_name:ident: $field_type:ty),* $(,)?
}
impl $interface:ident {
$($methods:tt)*
}
) => {
$vis struct $args$(<$($generic_type,)+>)?
$(where
$($generic_type: $first_generic_type_bound $(+ $generic_type_bound)*,)+
)?
{
$(pub(crate) $field_name: $field_type,)*
}
$wrap! {
$vis struct $name$(<$($generic_type: $first_generic_type_bound $(+ $generic_type_bound)*),+>)? {
$($field_vis $field_name: $field_type,)*
}
impl $interface {
$($methods)*
}
}
impl$(<$($generic_type,)+>)? $name$(<$($generic_type,)+>)?
$(where
$($generic_type: $first_generic_type_bound $(+ $generic_type_bound)*,)+
)?
{
$vis fn build(args: $args$(<$($generic_type,)+>)?) -> $interface {
Self::new($(args.$field_name),*)
}
}
};
}
pub(crate) use wrap_with_args;