#![allow(clippy::wildcard_imports)]
use super::*; use macro_tools::{
generic_params,
generic_args,
derive,
Result,
proc_macro2::TokenStream,
quote::{format_ident, quote},
ident, syn, parse_quote
};
#[ allow( clippy::too_many_lines ) ]
pub fn former_for_struct(
ast: &syn::DeriveInput,
_data_struct: &syn::DataStruct,
original_input: ¯o_tools::proc_macro2::TokenStream,
item_attributes: &ItemAttributes, has_debug: bool, ) -> Result< TokenStream > {
use macro_tools::IntoGenericArgs;
use convert_case::{Case, Casing};
let struct_attrs = item_attributes;
let vis = &ast.vis; let item = &ast.ident; let former = format_ident!("{item}Former"); let former_storage = format_ident!("{item}FormerStorage"); let former_definition = format_ident!("{item}FormerDefinition"); let former_definition_types = format_ident!("{item}FormerDefinitionTypes"); let as_subformer = format_ident!("{item}AsSubformer"); let as_subformer_end = format_ident!("{item}AsSubformerEnd");
let as_subformer_end_doc = format!(
r"
Represents an end condition for former of [`${item}`], tying the lifecycle of forming processes to a broader context.
This trait is intended for use with subformer alias, ensuring that end conditions are met according to the
specific needs of the broader forming context. It mandates the implementation of `former::FormingEnd`.
"
);
let generics = &ast.generics;
let (
struct_generics_with_defaults, struct_generics_impl, struct_generics_ty, struct_generics_where, ) = generic_params::decompose(generics);
let generics_ref = generic_params::GenericsRef::new(generics);
let classification = generics_ref.classification();
#[ allow( clippy::no_effect_underscore_binding ) ]
let _has_only_lifetimes = classification.has_only_lifetimes;
#[ cfg( feature = "former_diagnostics_print_generated" ) ]
if has_debug {
eprintln!("Struct: {item}");
eprintln!("has_only_lifetimes: {}", classification.has_only_lifetimes);
eprintln!("has_only_types: {}", classification.has_only_types);
eprintln!("has_mixed: {}", classification.has_mixed);
eprintln!("classification: {classification:?}");
}
let struct_type_ref = if struct_generics_ty.is_empty() {
quote! { #item }
} else {
quote! { #item < #struct_generics_ty > }
};
let storage_type_ref = if struct_generics_ty.is_empty() {
quote! { #former_storage }
} else {
quote! { #former_storage < #struct_generics_ty > }
};
let struct_impl_generics = if struct_generics_impl.is_empty() {
quote! {}
} else {
quote! { < #struct_generics_impl > }
};
let struct_where_clause = if struct_generics_where.is_empty() {
quote! {}
} else {
quote! { where #struct_generics_where }
};
let _lifetimes: Vec< _ > = generics.lifetimes().cloned().collect();
let struct_generics_impl_without_lifetimes = generic_params::filter_params(
&struct_generics_impl,
generic_params::filter_non_lifetimes
);
let _struct_generics_ty_without_lifetimes = generic_params::filter_params(
&struct_generics_ty,
generic_params::filter_non_lifetimes
);
let _struct_generics_impl_without_lifetimes_with_comma = if struct_generics_impl_without_lifetimes.is_empty() {
quote! {}
} else {
quote! { #struct_generics_impl_without_lifetimes , }
};
let extra: macro_tools::syn::AngleBracketedGenericArguments = parse_quote! {
< (), #struct_type_ref, former::ReturnPreformed > };
let former_definition_args = generic_args::merge(&generics.into_generic_args(), &extra).args;
#[allow(clippy::used_underscore_binding)]
let (former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where, former_type_ref, _former_type_full, former_impl_generics, former_type_concrete) = if classification.has_only_lifetimes {
let lifetimes_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_lifetimes);
let mut lifetimes_only_generics = ast.generics.clone();
lifetimes_only_generics.params = lifetimes_only_params;
let extra: macro_tools::generic_params::GenericsWithWhere = parse_quote! {
< Definition = #former_definition < #former_definition_args > >
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
Definition::Types : former::FormerDefinitionTypes< Storage = #storage_type_ref >,
};
let merged = generic_params::merge(&lifetimes_only_generics, &extra.into());
let (former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where) = generic_params::decompose(&merged);
let (former_type_ref, _former_type_full, former_impl_generics, former_type_concrete) = if lifetimes_only_generics.params.is_empty() {
(
quote! { #former < Definition > },
quote! { #former < Definition > },
quote! { < Definition > },
quote! { #former < #former_definition < #former_definition_args > > }
)
} else {
let (_, _, lifetimes_ty, _) = generic_params::decompose(&lifetimes_only_generics);
(
quote! { #former < #lifetimes_ty, Definition > },
quote! { #former < #lifetimes_ty, Definition > },
quote! { < #lifetimes_ty, Definition > },
quote! { #former < #lifetimes_ty, #former_definition < #former_definition_args > > }
)
};
(former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where, former_type_ref, _former_type_full, former_impl_generics, former_type_concrete)
} else if classification.has_only_types {
let types_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_types);
let mut types_only_generics = ast.generics.clone();
types_only_generics.params = types_only_params;
let extra: macro_tools::generic_params::GenericsWithWhere = parse_quote! {
< Definition = #former_definition < #former_definition_args > >
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
Definition::Types : former::FormerDefinitionTypes< Storage = #storage_type_ref >,
};
let merged = generic_params::merge(&types_only_generics, &extra.into());
let (former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where) = generic_params::decompose(&merged);
let (former_type_ref, _former_type_full, former_impl_generics, former_type_concrete) = if types_only_generics.params.is_empty() {
(
quote! { #former < Definition > },
quote! { #former < Definition > },
quote! { < Definition > },
quote! { #former < #former_definition < #former_definition_args > > }
)
} else {
let (_, _, types_ty, _) = generic_params::decompose(&types_only_generics);
(
quote! { #former < #types_ty, Definition > },
quote! { #former < #types_ty, Definition > },
quote! { < #types_ty, Definition > },
quote! { #former < #types_ty, #former_definition < #former_definition_args > > }
)
};
(former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where, former_type_ref, _former_type_full, former_impl_generics, former_type_concrete)
} else {
let empty_generics = syn::Generics::default();
let extra: macro_tools::generic_params::GenericsWithWhere = parse_quote! {
< Definition = #former_definition < #former_definition_args > >
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
Definition::Types : former::FormerDefinitionTypes< Storage = #storage_type_ref >,
};
let merged = generic_params::merge(&empty_generics, &extra.into());
let (former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where) = generic_params::decompose(&merged);
let (former_type_ref, _former_type_full, former_impl_generics, former_type_concrete) = (
quote! { #former < Definition > },
quote! { #former < Definition > },
quote! { < Definition > },
quote! { #former < #former_definition < #former_definition_args > > }
);
(former_generics_with_defaults, former_generics_impl, former_generics_ty, former_generics_where, former_type_ref, _former_type_full, former_impl_generics, former_type_concrete)
};
let (former_begin_impl_generics, former_begin_trait_lifetime, former_begin_additional_bounds) = if classification.is_empty {
(quote! { < 'a, Definition > }, quote! { 'a }, quote! { Definition::Context : 'a, Definition::End : 'a})
} else if classification.has_only_lifetimes {
let lifetimes_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_lifetimes);
let mut lifetimes_only_generics = ast.generics.clone();
lifetimes_only_generics.params = lifetimes_only_params;
if lifetimes_only_generics.params.is_empty() {
(quote! { < 'storage, Definition > }, quote! { 'storage }, quote! {})
} else {
let (_, lifetimes_impl, _, _) = generic_params::decompose(&lifetimes_only_generics);
let first_lifetime = if let Some(syn::GenericParam::Lifetime(ref lp)) = lifetimes_only_generics.params.first() {
&lp.lifetime
} else {
return Err(syn::Error::new_spanned(ast, "Expected lifetime parameter"));
};
(
quote! { < #lifetimes_impl, 'storage, Definition > },
quote! { 'storage },
quote! { #first_lifetime : 'storage, Definition::Context : 'storage, Definition::End : 'storage }
)
}
} else if classification.has_only_types {
let types_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_types);
let mut types_only_generics = ast.generics.clone();
types_only_generics.params = types_only_params;
if types_only_generics.params.is_empty() {
(quote! { < 'a, Definition > }, quote! { 'a }, quote! { Definition::Context : 'a, Definition::End : 'a})
} else {
let (_, types_impl, _, _) = generic_params::decompose(&types_only_generics);
let type_bounds = types_only_generics.params.iter().map(|param| {
if let syn::GenericParam::Type(type_param) = param {
let ident = &type_param.ident;
quote! { #ident : 'a }
} else {
quote! {}
}
});
(
quote! { < 'a, #types_impl, Definition > },
quote! { 'a },
quote! { #(#type_bounds),*, Definition::Context : 'a, Definition::End : 'a}
)
}
} else {
(quote! { < 'a, Definition > }, quote! { 'a }, quote! {})
};
let perform_base_generics = if classification.has_only_lifetimes {
let lifetimes_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_lifetimes);
let mut lifetimes_only_generics = ast.generics.clone();
lifetimes_only_generics.params = lifetimes_only_params;
lifetimes_only_generics
} else if classification.has_only_types {
let types_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_types);
let mut types_only_generics = ast.generics.clone();
types_only_generics.params = types_only_params;
types_only_generics
} else {
syn::Generics::default()
};
let extra: macro_tools::generic_params::GenericsWithWhere = parse_quote! {
< Definition >
where
Definition : former::FormerDefinition< Storage = #storage_type_ref, Formed = #struct_type_ref >,
Definition::Types : former::FormerDefinitionTypes< Storage = #storage_type_ref, Formed = #struct_type_ref >,
};
let merged = generic_params::merge(&perform_base_generics, &extra.into());
let (
_former_perform_generics_with_defaults,
former_perform_generics_impl,
_former_perform_generics_ty,
former_perform_generics_where,
) = generic_params::decompose(&merged);
let _former_perform_generics_ty_clean = quote! { Definition };
let former_perform_impl_generics = if former_perform_generics_impl.is_empty() {
quote! { < Definition > }
} else {
quote! { < #former_perform_generics_impl > }
};
let former_perform_type_generics = if classification.has_only_lifetimes {
let lifetimes_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_lifetimes);
let mut lifetimes_only_generics = ast.generics.clone();
lifetimes_only_generics.params = lifetimes_only_params;
if lifetimes_only_generics.params.is_empty() {
quote! { < Definition > }
} else {
let (_, _, lifetimes_ty, _) = generic_params::decompose(&lifetimes_only_generics);
quote! { < #lifetimes_ty, Definition > }
}
} else if classification.has_only_types {
let types_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_types);
let mut types_only_generics = ast.generics.clone();
types_only_generics.params = types_only_params;
if types_only_generics.params.is_empty() {
quote! { < Definition > }
} else {
let (_, _, types_ty, _) = generic_params::decompose(&types_only_generics);
quote! { < #types_ty, Definition > }
}
} else {
quote! { < Definition > }
};
let extra: macro_tools::generic_params::GenericsWithWhere = parse_quote! {
< __Context = (), __Formed = #struct_type_ref >
};
let former_definition_types_generics = generic_params::merge(generics, &extra.into());
let (
former_definition_types_generics_with_defaults,
former_definition_types_generics_impl,
former_definition_types_generics_ty,
former_definition_types_generics_where,
) = generic_params::decompose(&former_definition_types_generics);
let former_definition_types_phantom = macro_tools::phantom::tuple(&former_definition_types_generics_impl);
let former_definition_types_impl_generics = if struct_generics_impl.is_empty() {
quote! { < __Context, __Formed > }
} else {
quote! { < #former_definition_types_generics_impl > }
};
let former_definition_types_where_clause = if former_definition_types_generics_where.is_empty() {
quote! {}
} else {
quote! { where #former_definition_types_generics_where }
};
let former_definition_types_ref = if struct_generics_ty.is_empty() {
quote! { #former_definition_types < __Context, __Formed > }
} else {
quote! { #former_definition_types < #former_definition_types_generics_ty > }
};
let extra: macro_tools::generic_params::GenericsWithWhere = parse_quote! {
< __Context = (), __Formed = #struct_type_ref, __End = former::ReturnPreformed >
};
let generics_of_definition = generic_params::merge(generics, &extra.into());
let (
former_definition_generics_with_defaults,
former_definition_generics_impl,
former_definition_generics_ty,
former_definition_generics_where,
) = generic_params::decompose(&generics_of_definition);
let former_definition_phantom = macro_tools::phantom::tuple(&former_definition_generics_impl);
let former_definition_impl_generics = if struct_generics_impl.is_empty() {
quote! { < __Context, __Formed, __End > }
} else {
quote! { < #former_definition_generics_impl > }
};
let former_definition_where_clause = if former_definition_generics_where.is_empty() {
quote! {}
} else {
quote! { where #former_definition_generics_where }
};
let former_definition_where_clause_with_end = if former_definition_generics_where.is_empty() {
quote! {
where
__End : former::FormingEnd< #former_definition_types_ref >
}
} else {
quote! {
where
__End : former::FormingEnd< #former_definition_types_ref >,
#former_definition_generics_where
}
};
let former_definition_ref = if struct_generics_ty.is_empty() {
quote! { #former_definition < __Context, __Formed, __End > }
} else {
quote! { #former_definition < #former_definition_generics_ty > }
};
let as_subformer_definition = if struct_generics_ty.is_empty() {
quote! { #former_definition < __Superformer, __Superformer, __End > }
} else {
quote! { #former_definition < #struct_generics_ty, __Superformer, __Superformer, __End > }
};
let as_subformer_former = if struct_generics_ty.is_empty() {
quote! { #former < #as_subformer_definition > }
} else {
quote! { #former < #struct_generics_ty, #as_subformer_definition > }
};
let as_subformer_end_definition_types = if struct_generics_ty.is_empty() {
quote! { #former_definition_types < SuperFormer, SuperFormer > }
} else {
quote! { #former_definition_types < #struct_generics_ty, SuperFormer, SuperFormer > }
};
let as_subformer_alias = if struct_generics_ty.is_empty() {
quote! { #vis type #as_subformer < __Superformer, __End > = #as_subformer_former; }
} else {
quote! { #vis type #as_subformer < #struct_generics_ty, __Superformer, __End > = #as_subformer_former; }
};
let as_subformer_end_trait = if struct_generics_ty.is_empty() {
quote! { pub trait #as_subformer_end < SuperFormer > }
} else {
quote! { pub trait #as_subformer_end < #struct_generics_ty, SuperFormer > }
};
let as_subformer_end_impl = if struct_generics_ty.is_empty() {
quote! { impl< SuperFormer, __T > #as_subformer_end < SuperFormer > }
} else {
quote! { impl< #struct_generics_impl, SuperFormer, __T > #as_subformer_end < #struct_generics_ty, SuperFormer > }
};
let as_subformer_end_where_clause = if struct_generics_where.is_empty() {
quote! {
where
Self : former::FormingEnd
< #as_subformer_end_definition_types
> }
} else {
quote! {
where
Self : former::FormingEnd
< #as_subformer_end_definition_types
>, #struct_generics_where
}
};
let (_doc_former_mod, doc_former_struct) = doc_generate(item);
let (perform, perform_output, perform_generics) = struct_attrs.performer()?;
let fields = derive::named_fields(ast)?;
let mut formed_fields = Vec::with_capacity(fields.len());
for field in fields {
formed_fields.push(FormerField::from_syn(field, true, true)?);
}
let storage_fields_input = struct_attrs.storage_fields();
let mut storage_fields = Vec::with_capacity(storage_fields_input.len());
for field in storage_fields_input {
storage_fields.push(FormerField::from_syn(field, true, false)?);
}
let mut constructor_args_fields = Vec::with_capacity(formed_fields.len());
for field in &formed_fields {
if !field.attrs.former_ignore.value(false) {
constructor_args_fields.push(field);
}
}
let constructor_params = constructor_args_fields.iter().map(| f | {
let ident = f.ident;
let ty = f.non_optional_ty; let param_name = ident::ident_maybe_raw( ident );
quote! { #param_name : impl ::core::convert::Into< #ty > }
});
let constructor_storage_assignments = constructor_args_fields.iter().map(| f | {
let ident = f.ident;
let param_name = ident::ident_maybe_raw( ident );
quote! { #ident : ::core::option::Option::Some( #param_name.into() ) }
});
let non_constructor_storage_assignments = formed_fields
.iter()
.chain( storage_fields.iter() ) .filter( | f | f.attrs.former_ignore.value( false ) ) .map( | f | {
let ident = f.ident;
quote! { #ident : ::core::option::Option::None }
});
let all_storage_assignments = constructor_storage_assignments.chain(non_constructor_storage_assignments);
let initial_storage_code = if constructor_args_fields.is_empty() {
quote! { ::core::option::Option::None }
} else {
quote! {
::core::option::Option::Some
( #storage_type_ref {
#( #all_storage_assignments ),*
}
) }
};
let all_fields: Vec<&FormerField<'_>> = formed_fields.iter().chain(storage_fields.iter()).collect();
let total_fields = all_fields.len();
let mut storage_field_none = Vec::with_capacity(total_fields);
let mut storage_field_optional = Vec::with_capacity(total_fields);
let mut storage_field_name = Vec::with_capacity(total_fields);
let mut storage_field_preform = Vec::with_capacity(total_fields);
let mut former_field_setter = Vec::with_capacity(total_fields);
for field in all_fields {
storage_field_none.push(field.storage_fields_none());
storage_field_optional.push(field.storage_field_optional());
storage_field_name.push(field.storage_field_name());
storage_field_preform.push(field.storage_field_preform()?);
former_field_setter.push(field.former_field_setter(
item,
original_input,
&struct_generics_impl,
&struct_generics_ty,
&struct_generics_where,
&former,
&former_generics_impl,
&former_generics_ty,
&former_generics_where,
&former_storage,
)?);
}
let (former_field_setter, namespace_code): (Vec< _ >, Vec< _ >) = former_field_setter.into_iter().unzip();
let _former_mutator_code = mutator( item,
original_input,
&struct_attrs.mutator,
&former_definition_types,
&FormerDefinitionTypesGenerics { impl_generics: &former_definition_types_generics_impl,
ty_generics: &former_definition_types_generics_ty,
where_clause: &former_definition_types_generics_where,
},
&former_definition_types_ref,
)?;
let standalone_constructor_code = if struct_attrs.standalone_constructors.value(false) {
let constructor_name_str = item.to_string().to_case(Case::Snake);
let constructor_name_ident_temp = format_ident!("{}", constructor_name_str, span = item.span());
let constructor_name = ident::ident_maybe_raw(&constructor_name_ident_temp);
let all_fields_are_args = formed_fields.iter().all(|f| {
if f.attrs.former_ignore.value(false) {
false } else {
true }
});
let (return_type, constructor_body) = if all_fields_are_args {
let return_type = quote! { #struct_type_ref };
let construction_args = formed_fields.iter().map(| f | {
let field_ident = f.ident;
let is_constructor_arg = if f.attrs.former_ignore.value(false) {
false } else {
true };
if is_constructor_arg {
let param_name = ident::ident_maybe_raw( field_ident );
quote! { #field_ident : #param_name.into() }
} else {
quote! { #field_ident : ::core::default::Default::default() }
}
});
let body = quote! { #struct_type_ref { #( #construction_args ),* } };
(return_type, body)
} else {
let former_body = quote! {
#former::begin( #initial_storage_code, None, former::ReturnPreformed )
};
(former_type_concrete.clone(), former_body) };
quote! {
#[ inline( always ) ]
#vis fn #constructor_name < #struct_generics_impl >
( #( #constructor_params ),* ) ->
#return_type where
#struct_generics_where {
#constructor_body }
}
} else {
quote! {}
};
let entity_to_former_impl_generics = generic_params::params_with_additional(
&struct_generics_impl,
&[parse_quote! { Definition }],
);
let entity_to_former_ty_generics = if classification.has_only_lifetimes {
let lifetimes_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_lifetimes);
let mut lifetimes_only_generics = ast.generics.clone();
lifetimes_only_generics.params = lifetimes_only_params;
if lifetimes_only_generics.params.is_empty() {
quote! { Definition }
} else {
let (_, _, lifetimes_ty, _) = generic_params::decompose(&lifetimes_only_generics);
quote! { #lifetimes_ty, Definition }
}
} else if classification.has_only_types {
let types_only_params = generic_params::filter_params(&ast.generics.params, generic_params::filter_types);
let mut types_only_generics = ast.generics.clone();
types_only_generics.params = types_only_params;
if types_only_generics.params.is_empty() {
quote! { Definition }
} else {
let (_, _, types_ty, _) = generic_params::decompose(&types_only_generics);
quote! { #types_ty, Definition }
}
} else {
quote! { Definition }
};
let additional_params: syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma> =
parse_quote! { __Context, __Formed, __End };
let entity_to_definition_impl_generics = generic_params::merge_params_ordered(
&[&struct_generics_impl, &additional_params],
);
let additional_params: syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma> =
parse_quote! { __Context, __Formed };
let definition_types_ty_generics = generic_params::merge_params_ordered(
&[&struct_generics_ty, &additional_params],
);
let additional_params: syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma> =
parse_quote! { __Context, __Formed, __End };
let definition_ty_generics = generic_params::merge_params_ordered(
&[&struct_generics_ty, &additional_params],
);
let additional_params: syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma> =
parse_quote! { __Context, __Formed };
let entity_to_definition_types_impl_generics = generic_params::merge_params_ordered(
&[&struct_generics_impl, &additional_params],
);
let _former_begin_where_clause = if classification.has_only_types {
quote! {}
} else {
quote! { , #struct_generics_where }
};
let former_begin_final_where_clause = if struct_generics_where.is_empty() {
if former_begin_additional_bounds.is_empty() {
quote! {
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >
}
} else {
quote! {
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
#former_begin_additional_bounds
}
}
} else if former_begin_additional_bounds.is_empty() {
quote! {
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
#struct_generics_where
}
} else {
quote! {
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
#struct_generics_where #former_begin_additional_bounds
}
};
let result = quote! {
#[ automatically_derived ]
impl #struct_impl_generics #struct_type_ref
#struct_where_clause
{
#[ inline( always ) ]
pub fn former() -> #former_type_concrete
{
#former::begin( None, None, former::ReturnPreformed )
}
}
#standalone_constructor_code
impl< #entity_to_former_impl_generics > former::EntityToFormer< Definition >
for #struct_type_ref
where
Definition : former::FormerDefinition< Storage = #storage_type_ref >,
#struct_generics_where
{
type Former = #former < #entity_to_former_ty_generics > ;
}
impl #struct_impl_generics former::EntityToStorage
for #struct_type_ref
#struct_where_clause
{
type Storage = #storage_type_ref;
}
impl< #entity_to_definition_impl_generics > former::EntityToDefinition< __Context, __Formed, __End >
for #struct_type_ref
where
__End : former::FormingEnd< #former_definition_types < #definition_types_ty_generics > >,
#struct_generics_where
{
type Definition = #former_definition < #definition_ty_generics >;
type Types = #former_definition_types < #definition_types_ty_generics >;
}
impl< #entity_to_definition_types_impl_generics > former::EntityToDefinitionTypes< __Context, __Formed >
for #struct_type_ref
#struct_where_clause
{
type Types = #former_definition_types < #definition_types_ty_generics >;
}
#[ derive( Debug ) ]
#vis struct #former_definition_types < #former_definition_types_generics_with_defaults >
#former_definition_types_where_clause
{
_phantom : #former_definition_types_phantom,
}
impl #former_definition_types_impl_generics ::core::default::Default
for #former_definition_types_ref
#former_definition_types_where_clause
{
fn default() -> Self
{
Self
{
_phantom : ::core::marker::PhantomData,
}
}
}
impl #former_definition_types_impl_generics former::FormerDefinitionTypes
for #former_definition_types_ref
#former_definition_types_where_clause
{
type Storage = #storage_type_ref;
type Formed = __Formed;
type Context = __Context;
}
#_former_mutator_code
#[ derive( Debug ) ]
#vis struct #former_definition < #former_definition_generics_with_defaults >
#former_definition_where_clause
{
_phantom : #former_definition_phantom,
}
impl #former_definition_impl_generics ::core::default::Default
for #former_definition_ref
#former_definition_where_clause
{
fn default() -> Self
{
Self
{
_phantom : ::core::marker::PhantomData,
}
}
}
impl #former_definition_impl_generics former::FormerDefinition
for #former_definition_ref
#former_definition_where_clause_with_end
{
type Types = #former_definition_types_ref;
type End = __End;
type Storage = #storage_type_ref;
type Formed = __Formed;
type Context = __Context;
}
#[ doc = "Stores potential values for fields during the formation process." ]
#[ allow( explicit_outlives_requirements ) ]
#vis struct #former_storage < #struct_generics_with_defaults >
#struct_where_clause
{
#(
#storage_field_optional,
)*
}
impl #struct_impl_generics ::core::default::Default
for #storage_type_ref
#struct_where_clause
{
#[ inline( always ) ]
fn default() -> Self
{
Self
{
#( #storage_field_none, )*
}
}
}
impl #struct_impl_generics former::Storage
for #storage_type_ref
#struct_where_clause
{
type Preformed = #struct_type_ref;
}
impl #struct_impl_generics former::StoragePreform
for #storage_type_ref
#struct_where_clause
{
fn preform( mut self ) -> Self::Preformed
{
#( #storage_field_preform )*
let result = #item
{
#( #storage_field_name )*
};
return result;
}
}
#[ doc = #doc_former_struct ]
#vis struct #former < #former_generics_with_defaults >
where
#former_generics_where
{
pub storage : Definition::Storage,
pub context : ::core::option::Option< Definition::Context >,
pub on_end : ::core::option::Option< Definition::End >,
}
#[ automatically_derived ]
impl #former_impl_generics #former_type_ref
where
#former_generics_where
{
#[ inline( always ) ]
pub fn new
( on_end : Definition::End
) -> Self {
Self::begin_coercing( ::core::option::Option::None, ::core::option::Option::None, on_end )
}
#[ inline( always ) ]
pub fn new_coercing< IntoEnd >
( end : IntoEnd
) -> Self where
IntoEnd : ::core::convert::Into< Definition::End >,
{
Self::begin_coercing
( ::core::option::Option::None,
::core::option::Option::None,
end,
) }
#[ inline( always ) ]
pub fn begin
( mut storage : ::core::option::Option< Definition::Storage >,
context : ::core::option::Option< Definition::Context >,
on_end : < Definition as former::FormerDefinition >::End,
) -> Self
{
if storage.is_none()
{
storage = ::core::option::Option::Some( ::core::default::Default::default() );
}
Self
{
storage : storage.unwrap(),
context : context,
on_end : ::core::option::Option::Some( on_end ),
}
}
#[ inline( always ) ]
pub fn begin_coercing< IntoEnd >
( mut storage : ::core::option::Option< Definition::Storage >,
context : ::core::option::Option< Definition::Context >,
on_end : IntoEnd,
) -> Self where
IntoEnd : ::core::convert::Into< < Definition as former::FormerDefinition >::End >,
{
if storage.is_none()
{
storage = ::core::option::Option::Some( ::core::default::Default::default() );
}
Self
{
storage : storage.unwrap(),
context : context,
on_end : ::core::option::Option::Some( ::core::convert::Into::into( on_end ) ),
}
}
#[ inline( always ) ]
pub fn form( self ) -> < Definition::Types as former::FormerDefinitionTypes >::Formed
{
self.end()
}
#[ inline( always ) ]
pub fn end( mut self ) -> < Definition::Types as former::FormerDefinitionTypes >::Formed
{
let on_end = self.on_end.take().unwrap();
let mut context = self.context.take();
< Definition::Types as former::FormerMutator >::form_mutation( &mut self.storage, &mut context );
former::FormingEnd::< Definition::Types >::call( &on_end, self.storage, context )
}
#(
#former_field_setter
)*
}
impl #former_impl_generics #former_type_ref
where
Definition : former::FormerDefinition< Storage = #storage_type_ref, Formed = #struct_type_ref >,
Definition::Types : former::FormerDefinitionTypes< Storage = #storage_type_ref, Formed = #struct_type_ref >,
#former_generics_where
{
pub fn preform( self ) -> < Definition::Types as former::FormerDefinitionTypes >::Formed
{
former::StoragePreform::preform( self.storage )
}
}
#[ automatically_derived ]
impl #former_perform_impl_generics #former #former_perform_type_generics
where
#former_perform_generics_where
{
#[ inline( always ) ]
pub fn perform #perform_generics ( self ) -> #perform_output
{
let result = self.form();
#perform
}
}
impl #former_begin_impl_generics former::FormerBegin< #former_begin_trait_lifetime, Definition >
for #former_type_ref
#former_begin_final_where_clause
{
#[ inline( always ) ]
fn former_begin
( storage : ::core::option::Option< Definition::Storage >,
context : ::core::option::Option< Definition::Context >,
on_end : Definition::End,
) -> Self
{
Self::begin( ::core::option::Option::None, context, on_end )
}
}
#as_subformer_alias
#[ doc = #as_subformer_end_doc ]
#as_subformer_end_trait
#as_subformer_end_where_clause
{
}
#as_subformer_end_impl
for __T
#as_subformer_end_where_clause
{
}
#( #namespace_code )*
};
if has_debug {
let about = format!("derive : Former\nstruct : {item}");
diag::report_print(about, original_input, &result);
}
#[ cfg( feature = "former_diagnostics_print_generated" ) ]
if has_debug && item.to_string().contains("TestLifetime") {
eprintln!("LIFETIME DEBUG: Generated code for {item}:");
eprintln!("{result}");
}
Ok(result)
}