#![ allow( missing_docs ) ]
use component_model_meta::*;
use component_model_types::*;
#[cfg(test)]
mod test_component_from_person
{
use super::*;
#[test]
fn documented_example_works()
{
#[ derive( ComponentFrom ) ]
struct Person
{
pub age: i32,
pub name: String,
}
let my_struct = Person { age: 10, name: "Hello".into() };
let age: i32 = From::from( &my_struct );
let name: String = From::from( &my_struct );
assert_eq!( age, 10 );
assert_eq!( name, "Hello" );
}
#[test]
fn single_field_struct()
{
#[ derive( ComponentFrom ) ]
struct OnlyAge
{
pub age: i32,
}
let obj = OnlyAge { age: 42 };
let age: i32 = From::from( &obj );
assert_eq!( age, 42 );
}
#[test]
fn three_fields_different_types()
{
#[ derive( ComponentFrom ) ]
struct TripleData
{
pub count: i32,
pub label: String,
pub ratio: f64,
}
let obj = TripleData
{
count: 100,
label: "test".into(),
ratio: 3.14,
};
let count: i32 = From::from( &obj );
let label: String = From::from( &obj );
let ratio: f64 = From::from( &obj );
assert_eq!( count, 100 );
assert_eq!( label, "test" );
assert_eq!( ratio, 3.14 );
}
#[test]
fn tuple_struct_single_field()
{
#[ derive( ComponentFrom ) ]
struct Wrapper( pub i32 );
let obj = Wrapper( 777 );
let val: i32 = From::from( &obj );
assert_eq!( val, 777 );
}
#[test]
fn tuple_struct_multiple_fields()
{
#[ derive( ComponentFrom ) ]
struct Pair( pub i32, pub String );
let obj = Pair( 123, "data".into() );
let num: i32 = From::from( &obj );
let text: String = From::from( &obj );
assert_eq!( num, 123 );
assert_eq!( text, "data" );
}
}
#[cfg(test)]
mod test_component_assign_person
{
use super::*;
#[test]
fn documented_example_works()
{
#[ derive( Default, PartialEq, Debug, Assign ) ]
struct Person
{
age: i32,
name: String,
}
let mut person: Person = Default::default();
person.assign( 13 );
person.assign( "John" );
assert_eq!( person, Person { age: 13, name: "John".to_string() } );
}
#[test]
fn single_field_assignment()
{
#[ derive( Default, PartialEq, Debug, Assign ) ]
struct Counter
{
count: i32,
}
let mut counter = Counter::default();
counter.assign( 999 );
assert_eq!( counter.count, 999 );
}
#[test]
fn into_conversion_on_assign()
{
#[ derive( Default, PartialEq, Debug, Assign ) ]
struct Data
{
label: String,
}
let mut data = Data::default();
data.assign( "test" ); assert_eq!( data.label, "test" );
}
#[test]
fn tuple_struct_assignment()
{
#[ derive( Default, PartialEq, Debug, Assign ) ]
struct Pair( i32, String );
let mut pair = Pair::default();
pair.assign( 42 );
pair.assign( "answer" );
assert_eq!( pair.0, 42 );
assert_eq!( pair.1, "answer" );
}
}
#[cfg(test)]
mod test_from_components_options
{
use super::*;
#[test]
fn documented_example_works()
{
#[ derive( Debug, Default, PartialEq ) ]
pub struct Options1
{
field1: i32,
field2: String,
field3: f32,
}
impl From< &Options1 > for i32
{
#[ inline( always ) ]
fn from( src: &Options1 ) -> Self
{
src.field1.clone()
}
}
impl From< &Options1 > for String
{
#[ inline( always ) ]
fn from( src: &Options1 ) -> Self
{
src.field2.clone()
}
}
impl From< &Options1 > for f32
{
#[ inline( always ) ]
fn from( src: &Options1 ) -> Self
{
src.field3.clone()
}
}
#[ derive( Debug, Default, PartialEq, FromComponents ) ]
pub struct Options2
{
field1: i32,
field2: String,
}
let o1 = Options1 { field1: 42, field2: "Hello, world!".to_string(), field3: 13.01 };
let o2: Options2 = Into::< Options2 >::into( &o1 );
let expected = Options2 { field1: 42, field2: "Hello, world!".to_string() };
assert_eq!( o2, expected );
let o2: Options2 = ( &o1 ).into();
assert_eq!( o2, expected );
let o2 = Options2::from( &o1 );
assert_eq!( o2, expected );
}
#[test]
fn single_field_conversion()
{
#[ derive( Debug, Default, PartialEq ) ]
struct Source
{
value: i32,
extra: String,
}
impl From< &Source > for i32
{
fn from( src: &Source ) -> Self
{
src.value
}
}
#[ derive( Debug, Default, PartialEq, FromComponents ) ]
struct Target
{
value: i32,
}
let source = Source { value: 100, extra: "ignored".into() };
let target: Target = ( &source ).into();
assert_eq!( target.value, 100 );
}
#[test]
fn equal_field_count_conversion()
{
#[ derive( Debug, Default, PartialEq ) ]
struct SourceData
{
id: i32,
name: String,
}
impl From< &SourceData > for i32
{
fn from( src: &SourceData ) -> Self
{
src.id
}
}
impl From< &SourceData > for String
{
fn from( src: &SourceData ) -> Self
{
src.name.clone()
}
}
#[ derive( Debug, Default, PartialEq, FromComponents ) ]
struct TargetData
{
id: i32,
name: String,
}
let source = SourceData { id: 999, name: "test".into() };
let target: TargetData = ( &source ).into();
assert_eq!( target.id, 999 );
assert_eq!( target.name, "test" );
}
}
#[cfg(test)]
mod test_component_model_config
{
use super::*;
#[test]
fn documented_example_works()
{
#[ derive( Default, ComponentModel ) ]
struct Config
{
host: String,
port: i32,
enabled: bool,
}
let mut config = Config::default();
config.assign( "localhost".to_string() );
config.assign( 8080i32 );
config.enabled_set( true );
assert_eq!( config.host, "localhost" );
assert_eq!( config.port, 8080 );
assert_eq!( config.enabled, true );
let config2 = Config::default()
.impute( "api.example.com".to_string() )
.impute( 3000i32 )
.enabled_with( false );
assert_eq!( config2.host, "api.example.com" );
assert_eq!( config2.port, 3000 );
assert_eq!( config2.enabled, false );
}
#[test]
fn single_field_component_model()
{
#[ derive( Default, ComponentModel ) ]
struct SimpleConfig
{
value: i32,
}
let mut config = SimpleConfig::default();
config.value_set( 123 );
assert_eq!( config.value, 123 );
let config2 = SimpleConfig::default().value_with( 456 );
assert_eq!( config2.value, 456 );
}
#[test]
fn many_fields_component_model()
{
#[ derive( Default, ComponentModel ) ]
struct LargeConfig
{
field1: i32,
field2: String,
field3: f64,
field4: bool,
field5: u64,
}
let config = LargeConfig::default()
.field1_with( 1 )
.field2_with( "two".to_string() )
.field3_with( 3.0 )
.field4_with( true )
.field5_with( 5u64 );
assert_eq!( config.field1, 1 );
assert_eq!( config.field2, "two" );
assert_eq!( config.field3, 3.0 );
assert_eq!( config.field4, true );
assert_eq!( config.field5, 5 );
}
#[test]
fn duplicate_types_handled()
{
#[ derive( Default, ComponentModel ) ]
struct DuplicateTypes
{
x: i32,
y: i32,
flag1: bool,
flag2: bool,
}
let obj = DuplicateTypes::default()
.x_with( 10 )
.y_with( 20 )
.flag1_with( true )
.flag2_with( false );
assert_eq!( obj.x, 10 );
assert_eq!( obj.y, 20 );
assert_eq!( obj.flag1, true );
assert_eq!( obj.flag2, false );
}
}
#[cfg(test)]
mod test_macro_combinations
{
use super::*;
#[test]
fn component_from_plus_assign()
{
#[ derive( Default, ComponentFrom, Assign ) ]
struct Data
{
value: i32,
label: String,
}
let mut obj = Data::default();
obj.assign( 99 );
obj.assign( "test" );
let extracted_value: i32 = From::from( &obj );
let extracted_label: String = From::from( &obj );
assert_eq!( extracted_value, 99 );
assert_eq!( extracted_label, "test" );
}
#[test]
fn round_trip_conversion()
{
#[ derive( Debug, PartialEq, Default, ComponentFrom, Assign ) ]
struct Original
{
id: i32,
name: String,
}
let obj1 = Original { id: 123, name: "original".into() };
let id: i32 = From::from( &obj1 );
let name: String = From::from( &obj1 );
let mut obj2 = Original::default();
obj2.assign( id );
obj2.assign( name );
assert_eq!( obj1, obj2 );
}
}