Derive Macro former::ComponentsAssign
source · #[derive(ComponentsAssign)]
{
// Attributes available to this derive:
#[debug]
}
Expand description
Derives the ComponentsAssign
trait for a struct, enabling components_assign
which set all fields at once.
This will work only if every field can be acquired from the passed value.
In other words, the type passed as an argument to components_assign
must implement Into
§Attributes
debug
: An optional attribute to enable debugging of the trait derivation process.
§Conditions
- This macro is only enabled when the
derive_components_assign
feature is active in yourCargo.toml
. - The type must implement
ComponentAssign
(derive( ComponentAssign )
)
§Limitations
This trait cannot be derived, if the struct has fields with identical types
§Input Code Example
An example when we encapsulate parameters passed to a function in a struct.
use former::{ ComponentAssign, ComponentsAssign };
#[ derive( Default, ComponentAssign, ComponentsAssign ) ]
struct BigOpts
{
cond : bool,
int : i32,
str : String,
}
#[ derive( Default, ComponentAssign, ComponentsAssign ) ]
struct SmallerOpts
{
cond: bool,
int: i32,
}
impl From< &BigOpts > for bool
{
fn from( value : &BigOpts ) -> Self
{
value.cond
}
}
impl From< &BigOpts > for i32
{
fn from( value: &BigOpts ) -> Self
{
value.int
}
}
fn take_big_opts( options : &BigOpts ) -> &String
{
&options.str
}
fn take_smaller_opts( options : &SmallerOpts ) -> bool
{
!options.cond
}
let options1 = BigOpts
{
cond : true,
int : -14,
..Default::default()
};
take_big_opts( &options1 );
let mut options2 = SmallerOpts::default();
options2.smaller_opts_assign( &options1 );
take_smaller_opts( &options2 );
Which expands approximately into :
use former::{ ComponentAssign, ComponentsAssign };
#[derive(Default)]
struct BigOpts
{
cond : bool,
int : i32,
str : String,
}
impl< IntoT > ComponentAssign< bool, IntoT > for BigOpts
where
IntoT : Into< bool >,
{
fn assign( &mut self, component : IntoT )
{
self.cond = component.into();
}
}
impl< IntoT > ComponentAssign< i32, IntoT > for BigOpts
where
IntoT : Into< i32 >,
{
fn assign( &mut self, component : IntoT )
{
self.int = component.into();
}
}
impl< IntoT > ComponentAssign< String, IntoT > for BigOpts
where
IntoT : Into< String >,
{
fn assign( &mut self, component : IntoT )
{
self.str = component.into();
}
}
pub trait BigOptsComponentsAssign< IntoT >
where
IntoT : Into< bool >,
IntoT : Into< i32 >,
IntoT : Into< String >,
IntoT : Clone,
{
fn components_assign( &mut self, component : IntoT );
}
impl< T, IntoT > BigOptsComponentsAssign< IntoT > for T
where
T : former::ComponentAssign< bool, IntoT >,
T : former::ComponentAssign< i32, IntoT >,
T : former::ComponentAssign< String, IntoT >,
IntoT : Into< bool >,
IntoT : Into< i32 >,
IntoT : Into< String >,
IntoT : Clone,
{
fn components_assign( &mut self, component : IntoT )
{
former::ComponentAssign::< bool, _ >::assign( self, component.clone() );
former::ComponentAssign::< i32, _ >::assign( self, component.clone() );
former::ComponentAssign::< String, _ >::assign( self, component.clone() );
}
}
#[derive(Default)]
struct SmallerOpts
{
cond : bool,
int : i32,
}
impl< IntoT > ComponentAssign< bool, IntoT > for SmallerOpts
where
IntoT : Into< bool >,
{
fn assign( &mut self, component : IntoT )
{
self.cond = component.into();
}
}
impl< IntoT > ComponentAssign< i32, IntoT > for SmallerOpts
where
IntoT : Into< i32 >,
{
fn assign( &mut self, component : IntoT )
{
self.int = component.into();
}
}
pub trait SmallerOptsComponentsAssign< IntoT >
where
IntoT : Into< bool >,
IntoT : Into< i32 >,
IntoT : Clone,
{
fn smaller_opts_assign( &mut self, component : IntoT );
}
impl< T, IntoT > SmallerOptsComponentsAssign< IntoT > for T
where
T : former::ComponentAssign< bool, IntoT >,
T : former::ComponentAssign< i32, IntoT >,
IntoT : Into< bool >,
IntoT : Into< i32 >,
IntoT : Clone,
{
fn smaller_opts_assign( &mut self, component : IntoT )
{
former::ComponentAssign::< bool, _ >::assign( self, component.clone() );
former::ComponentAssign::< i32, _ >::assign( self, component.clone() );
}
}
impl From< &BigOpts > for bool
{
fn from( value : &BigOpts ) -> Self
{
value.cond
}
}
impl From< &BigOpts > for i32
{
fn from( value : &BigOpts ) -> Self
{
value.int
}
}
fn take_big_opts( options : &BigOpts ) -> &String
{
&options.str
}
fn take_smaller_opts( options : &SmallerOpts ) -> bool
{
!options.cond
}
let options1 = BigOpts
{
cond : true,
int : -14,
..Default::default()
};
take_big_opts( &options1 );
let mut options2 = SmallerOpts::default();
options2.smaller_opts_assign( &options1 );
take_smaller_opts( &options2 );