Skip to content

Commit

Permalink
former : experimenting
Browse files Browse the repository at this point in the history
  • Loading branch information
Wandalen committed May 2, 2024
1 parent 92b0412 commit f171301
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,6 @@ pub struct Aggregator
command : HashMap< String, Command >,
}

// Use CommandFormer as custom subformer for AggregatorFormer to add commands by name.
impl< Definition > AggregatorFormer< Definition >
where
Definition : former::FormerDefinition< Storage = < Aggregator as former::EntityToStorage >::Storage >,
{

#[ inline( always ) ]
pub fn command( self, name : &str ) -> CommandAsSubformer< Self, impl CommandAsSubformerEnd< Self > >
{
self._command_add::< CommandFormer< _ >, _, >()
.name( name )
}

}

impl former::ValToElement< HashMap< String, Command > > for Command
{
type Element = ( String, Command );
Expand All @@ -58,10 +43,12 @@ fn basic()
{

let got = Aggregator::former()
.command( "echo" )
.command()
.name( "echo" )
.description( "prints all subjects and properties" ) // sets additional properties using custom subformer
.end()
.command( "exit" )
.command()
.name( "exit" )
.description( "just exit" ) // Sets additional properties using using custom subformer
.end()
.form();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#![ allow( dead_code ) ]

#[ allow( unused_imports ) ]
use super::*;
#[ allow( unused_imports ) ]
use collection_tools::HashMap;

// Command struct with Former derived for builder pattern support
#[ derive( Debug, PartialEq, former::Former ) ]
pub struct Command
{
name : String,
description : String,
}

// Aggregator struct to hold commands
#[ derive( Debug, PartialEq, former::Former ) ]
// #[ debug ]
// #[ derive( Debug, PartialEq ) ]
pub struct Aggregator
{
#[ subform( setter = false ) ]
#[ setter( false ) ]
command : HashMap< String, Command >,
}

// Use CommandFormer as custom subformer for AggregatorFormer to add commands by name.
impl< Definition > AggregatorFormer< Definition >
where
Definition : former::FormerDefinition< Storage = < Aggregator as former::EntityToStorage >::Storage >,
{

#[ inline( always ) ]
pub fn command( self, name : &str ) -> CommandAsSubformer< Self, impl CommandAsSubformerEnd< Self > >
{
self._command_add::< CommandFormer< _ >, _, >()
.name( name )
}

}

impl former::ValToElement< HashMap< String, Command > > for Command
{
type Element = ( String, Command );
#[ inline( always ) ]
fn val_to_element( self ) -> Self::Element
{
( self.name.clone(), self )
}
}

// == begin of generated

// == end of generated

#[ test ]
fn basic()
{

let got = Aggregator::former()
.command( "echo" )
.description( "prints all subjects and properties" ) // sets additional properties using custom subformer
.end()
.command( "exit" )
.description( "just exit" ) // Sets additional properties using using custom subformer
.end()
.form();

a_id!( got.command.len(), 2 );

}
// xxx
3 changes: 3 additions & 0 deletions module/core/former/tests/inc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ mod former_tests
mod subformer_subform_named;
#[ cfg( any( not( feature = "no_std" ) ) ) ]
mod subformer_subform_named_manual;

#[ cfg( any( not( feature = "no_std" ) ) ) ]
mod subformer_subform_hashmap;
#[ cfg( any( not( feature = "no_std" ) ) ) ]
mod subformer_subform_hashmap_explicit;

#[ cfg( any( not( feature = "no_std" ) ) ) ]
mod subformer_subform_and_container;
Expand Down
140 changes: 97 additions & 43 deletions module/core/former_meta/src/derive/former.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,58 @@ struct FormerField< 'a >
pub of_type : container_kind::ContainerKind,
}

// xxx
impl< 'a > FormerField< 'a >
{

/// Get name of setter for subform.
pub fn subform_setter_name( &self ) -> Option< &syn::Ident >
{

if let Some( ref attr ) = self.attrs.subform
{
if attr.setter
{
if let Some( ref name ) = attr.name
{
return Some( &name )
}
else
{
return Some( &self.ident )
}
}
}

return None;
}

/// Is trivial setter required.
pub fn trivial_setter_enabled( &self ) -> bool
{

if let Some( ref attr ) = self.attrs.setter
{
if attr.condition.value() == false
{
return false
}
}

let subform_name = self.subform_setter_name();
if let Some( name ) = subform_name
{
if self.ident == name
{
return false;
}
}

return true;
}

}

///
/// Attributes of the field.
///
Expand Down Expand Up @@ -264,17 +316,17 @@ struct AttributeSubform
/// - `name` : An optional identifier that names the subform. It is parsed from inputs
/// like `name = my_field`.
name : Option< syn::Ident >,
/// - `pubc` : An option for debug purpose.
#[ allow( dead_code ) ]
public : bool,
/// - `setter` : Disable generation of setter.
/// It still generate `_field_add` method, so it could be used to make a setter with custom arguments.
setter : bool,
}

impl syn::parse::Parse for AttributeSubform
{
fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self >
{
let mut name : Option< syn::Ident > = None;
let mut public : bool = true;
let mut setter : bool = true;

while !input.is_empty()
{
Expand All @@ -287,17 +339,13 @@ impl syn::parse::Parse for AttributeSubform
input.parse::< syn::Token![ = ] >()?;
name = Some( input.parse()? );
}
else if ident == "public"
else if ident == "setter"
{
input.parse::< syn::Token![ = ] >()?;
// Parse the boolean by checking next Ident if it's "true" or "false"
let value : syn::Ident = input.parse()?;
match value.to_string().as_str()
{
"true" => public = true,
"false" => public = false,
_ => return Err( syn::Error::new( value.span(), "expected `true` or `false`" ) ),
}
// let value : syn::Ident = input.parse()?;
let value : syn::LitBool = input.parse()?;
setter = value.value();
}
else
{
Expand All @@ -316,7 +364,7 @@ impl syn::parse::Parse for AttributeSubform
}
}

Ok( Self { name, public } )
Ok( Self { name, setter } )
}
}

Expand Down Expand Up @@ -642,24 +690,24 @@ fn field_setter_map
}
else
{
let setter_enabled = if let Some( setter_attr ) = &field.attrs.setter
{
if !setter_attr.condition.value()
{
false
}
else
{
true
}
}
else
{
true
};
if setter_enabled
// let setter_enabled = if let Some( setter_attr ) = &field.attrs.setter
// {
// if !setter_attr.condition.value()
// {
// false
// }
// else
// {
// true
// }
// }
// else
// {
// true
// };
if field.trivial_setter_enabled()
{
field_setter( ident, ident, non_optional_ty )
field_trivial_setter( ident, ident, non_optional_ty )
}
else
{
Expand All @@ -669,7 +717,7 @@ fn field_setter_map

let r = if let Some( alias_attr ) = &field.attrs.alias
{
let alias_tokens = field_setter( ident, &alias_attr.alias, non_optional_ty );
let alias_tokens = field_trivial_setter( ident, &alias_attr.alias, non_optional_ty );
qt!
{
#r
Expand Down Expand Up @@ -717,19 +765,24 @@ fn field_subform_add_setter_map
use convert_case::{ Case, Casing };
let field_ident = field.ident;
let field_ty = field.non_optional_ty;
let attr = field.attrs.subform.as_ref().unwrap();
// let params = typ::type_parameters( &field.non_optional_ty, .. );

// xxx

// example : `child`
let mut explicit_name = false;
let setter_name = if let Some( ref _name ) = field.attrs.subform.as_ref().unwrap().name
{
explicit_name = true;
_name
}
else
{
field_ident
};
// let mut explicit_name = false;
let setter_name = field.subform_setter_name();

// let setter_name = if let Some( ref name ) = attr.name
// {
// explicit_name = true;
// name
// }
// else
// {
// field_ident
// };

// example : `ParentFormerAddChildrenEnd``
let former_add_end_name = format!( "{}FormerAdd{}End", stru, field_ident.to_string().to_case( Case::Pascal ) );
Expand Down Expand Up @@ -768,7 +821,8 @@ fn field_subform_add_setter_map
};

// xxx : it should be printed by hint also
let r = if explicit_name
// let r = if explicit_name || attr.setter
let r = if attr.setter
{
qt!
{
Expand Down Expand Up @@ -1002,7 +1056,7 @@ fn field_container_setter
/// ```
#[ inline ]
fn field_setter
fn field_trivial_setter
(
field_ident : &syn::Ident,
setter_name : &syn::Ident,
Expand Down

0 comments on commit f171301

Please sign in to comment.