-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
READY : Allow to save nature order in commands & props #1325
Changes from 6 commits
6ef696f
e85ff9a
e59ee4c
c1b3a6e
039d5ab
e4cad1d
7e9244c
d551a3c
7279338
e6ab345
22f9eac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -100,7 +100,7 @@ pub( crate ) mod private | |||
/// ``` | ||||
#[ derive( Debug ) ] | ||||
#[ derive( former::Former ) ] | ||||
#[ storage_fields( help_generator : HelpGeneratorFn, help_variants : HashSet< HelpVariants > ) ] | ||||
#[ storage_fields( help_generator : HelpGeneratorFn, help_variants : HashSet< HelpVariants >, with_nature_sort : bool, order : Option< Vec< String > > ) ] | ||||
#[ mutator( custom = true ) ] | ||||
// #[ debug ] | ||||
pub struct CommandsAggregator | ||||
|
@@ -117,7 +117,7 @@ pub( crate ) mod private | |||
|
||||
#[ former( default = Verifier ) ] | ||||
verifier : Verifier, | ||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||||
callback_fn : Option< CommandsAggregatorCallback >, | ||||
} | ||||
|
||||
|
@@ -130,16 +130,25 @@ pub( crate ) mod private | |||
|
||||
let help_generator = std::mem::take( &mut ca.help_generator ).unwrap_or_default(); | ||||
let help_variants = std::mem::take( &mut ca.help_variants ).unwrap_or_else( || HashSet::from([ HelpVariants::All ]) ); | ||||
|
||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
let order = if ca.with_nature_sort.unwrap_or_default() | ||||
{ | ||||
std::mem::take( &mut ca.order ) | ||||
} | ||||
else | ||||
{ | ||||
None | ||||
}; | ||||
|
||||
if help_variants.contains( &HelpVariants::All ) | ||||
{ | ||||
HelpVariants::All.generate( &help_generator, dictionary ); | ||||
HelpVariants::All.generate( &help_generator, dictionary, order.clone() ); | ||||
} | ||||
else | ||||
{ | ||||
for help in help_variants.iter().sorted() | ||||
{ | ||||
help.generate( &help_generator, dictionary ); | ||||
help.generate( &help_generator, dictionary, order.clone() ); | ||||
} | ||||
} | ||||
} | ||||
|
@@ -154,10 +163,14 @@ pub( crate ) mod private | |||
/// # Arguments | ||||
/// | ||||
/// * `name` - The name of the command. | ||||
pub fn command< IntoName >( self, name : IntoName ) -> CommandAsSubformer< Self, impl CommandAsSubformerEnd< Self > > | ||||
pub fn command< IntoName >( mut self, name : IntoName ) -> CommandAsSubformer< Self, impl CommandAsSubformerEnd< Self > > | ||||
where | ||||
IntoName : Into< String >, | ||||
{ | ||||
let name = name.into(); | ||||
let mut order = self.storage.order.unwrap_or_default(); | ||||
order.push( name.clone() ); | ||||
self.storage.order = Some( order ); | ||||
let on_end = | command : CommandFormerStorage, super_former : Option< Self > | -> Self | ||||
{ | ||||
let mut super_former = super_former.unwrap(); | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,7 +86,6 @@ pub( crate ) mod private | |
|
||
#[ derive( Debug, Clone, PartialEq, Eq ) ] | ||
#[ derive( Former ) ] | ||
// #[ debug ] | ||
pub struct Command | ||
{ | ||
/// Command common hint. | ||
|
@@ -100,6 +99,8 @@ pub( crate ) mod private | |
pub subjects : Vec< ValueDescription >, | ||
/// Hints and types for command options. | ||
pub properties : HashMap< String, ValueDescription >, | ||
/// | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you write concise documentation |
||
pub properties_order : Vec< String >, | ||
/// Map of aliases. | ||
// Aliased key -> Original key | ||
pub properties_aliases : HashMap< String, String >, | ||
|
@@ -200,6 +201,8 @@ pub( crate ) mod private | |
let mut super_former = super_former.unwrap(); | ||
let mut properties = super_former.storage.properties.unwrap_or_default(); | ||
let property = property.preform(); | ||
let mut order = super_former.storage.properties_order.unwrap_or_default(); | ||
|
||
let value = ValueDescription | ||
{ | ||
hint : property.hint, | ||
|
@@ -208,6 +211,7 @@ pub( crate ) mod private | |
}; | ||
debug_assert!( !properties.contains_key( &property.name ), "Property name `{}` is already used for `{:?}`", property.name, properties[ &property.name ] ); | ||
properties.insert( property.name.clone(), value ); | ||
order.push( property.name.clone() ); | ||
|
||
let mut aliases = super_former.storage.properties_aliases.unwrap_or_default(); | ||
debug_assert!( !aliases.contains_key( &property.name ), "Name `{}` is already used for `{}` as alias", property.name, aliases[ &property.name ] ); | ||
|
@@ -216,6 +220,7 @@ pub( crate ) mod private | |
|
||
super_former.storage.properties = Some( properties ); | ||
super_former.storage.properties_aliases = Some( aliases ); | ||
super_former.storage.properties_order = Some( order ); | ||
|
||
super_former | ||
}; | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -53,6 +53,11 @@ pub( crate ) mod private | |||||
pub description_detailing : LevelOfDetail, | ||||||
/// If enabled - shows complete description of subjects and properties | ||||||
pub with_footer : bool, | ||||||
|
||||||
order : Option< Vec< String > >, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you write concise documentation |
||||||
|
||||||
// #[ former( default = true ) ] | ||||||
with_nature_order : bool, | ||||||
} | ||||||
|
||||||
// qqq : for Barsik : make possible to change properties order | ||||||
|
@@ -90,13 +95,21 @@ pub( crate ) mod private | |||||
LevelOfDetail::None => "".into(), | ||||||
_ if command.subjects.is_empty() => "".into(), | ||||||
LevelOfDetail::Simple => "< properties >".into(), | ||||||
LevelOfDetail::Detailed if o.with_nature_order => command.properties_order.iter().map( | n | format!( "< {n}:{}{:?} >", if command.properties.get(n).unwrap().optional { "?" } else { "" }, command.properties.get(n).unwrap().kind ) ).collect::< Vec< _ > >().join( " " ), | ||||||
LevelOfDetail::Detailed => command.properties.iter().map( |( n, v )| format!( "< {n}:{}{:?} >", if v.optional { "?" } else { "" }, v.kind ) ).collect::< Vec< _ > >().join( " " ), | ||||||
}; | ||||||
|
||||||
let footer = if o.with_footer | ||||||
{ | ||||||
let full_subjects = command.subjects.iter().map( | subj | format!( "- {} [{}{:?}]", subj.hint, if subj.optional { "?" } else { "" }, subj.kind ) ).join( "\n\t" ); | ||||||
let full_properties = format_table( command.properties.iter().sorted_by_key( |( name, _ )| *name ).map( |( name, value )| [ name.clone(), format!( "- {} [{}{:?}]", value.hint, if value.optional { "?" } else { "" }, value.kind ) ] ) ).unwrap().replace( '\n', "\n\t" ); | ||||||
let full_properties = if o.with_nature_order | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
format_table( command.properties_order.iter().map( | name | [ name.clone(), format!( "- {} [{}{:?}]", command.properties.get( name ).unwrap().hint, if command.properties.get( name ).unwrap().optional { "?" } else { "" }, command.properties.get( name ).unwrap().kind ) ] ) ).unwrap().replace( '\n', "\n\t" ) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can avoid duplication here, can't we? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you fmt this? |
||||||
} | ||||||
else | ||||||
{ | ||||||
format_table( command.properties.iter().sorted_by_key( |( name, _ )| *name ).map( |( name, value )| [ name.clone(), format!( "- {} [{}{:?}]", value.hint, if value.optional { "?" } else { "" }, value.kind ) ] ) ).unwrap().replace( '\n', "\n\t" ) | ||||||
}; | ||||||
format! | ||||||
( | ||||||
"{}{}", | ||||||
|
@@ -130,14 +143,25 @@ pub( crate ) mod private | |||||
} | ||||||
else | ||||||
{ | ||||||
let rows = dictionary.commands | ||||||
.iter() | ||||||
.sorted_by_key( |( name, _ )| *name ) | ||||||
.map( |( _, cmd )| cmd ) | ||||||
.map( for_single_command ) | ||||||
.map( | row | [ row.name, row.args, row.hint ] ); | ||||||
|
||||||
format_table( rows ).unwrap() | ||||||
if let Some(order) = o.order | ||||||
{ | ||||||
let rows = order | ||||||
.iter() | ||||||
.map( | k | dictionary.commands.get( k ).unwrap() ) | ||||||
.map( for_single_command ) | ||||||
.map( | row | [ row.name, row.args, row.hint ] ); | ||||||
format_table( rows ).unwrap() | ||||||
} | ||||||
else | ||||||
{ | ||||||
let rows = dictionary.commands | ||||||
.iter() | ||||||
.sorted_by_key( |( name, _ )| *name ) | ||||||
.map( |( _, cmd )| cmd ) | ||||||
.map( for_single_command ) | ||||||
.map( | row | [ row.name, row.args, row.hint ] ); | ||||||
format_table( rows ).unwrap() | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -158,25 +182,27 @@ pub( crate ) mod private | |||||
impl HelpVariants | ||||||
{ | ||||||
/// Generates help commands | ||||||
pub fn generate( &self, helper : &HelpGeneratorFn, dictionary : &mut Dictionary ) | ||||||
pub fn generate( &self, helper : &HelpGeneratorFn, dictionary : &mut Dictionary, order : Option< Vec< String > > ) | ||||||
{ | ||||||
// debug_assert!( dictionary.commands.len() == order.as_ref().map( | o | o.len() ).unwrap_or( dictionary.commands.len() ) ); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove redundant comments, please |
||||||
// dictionary.commands.keys().for_each( | k | assert!( order.as_ref().map( | a | a.contains( &k ) ).unwrap_or( true ) ) ); | ||||||
match self | ||||||
{ | ||||||
HelpVariants::All => | ||||||
{ | ||||||
self.general_help( helper, dictionary ); | ||||||
self.subject_command_help( helper, dictionary ); | ||||||
self.general_help( helper, dictionary, order.clone() ); | ||||||
self.subject_command_help( helper, dictionary, order ); | ||||||
// self.dot_command_help( helper, dictionary ); | ||||||
}, | ||||||
HelpVariants::General => self.general_help( helper, dictionary ), | ||||||
HelpVariants::SubjectCommand => self.subject_command_help( helper, dictionary ), | ||||||
HelpVariants::General => self.general_help( helper, dictionary, order ), | ||||||
HelpVariants::SubjectCommand => self.subject_command_help( helper, dictionary, order ), | ||||||
_ => unimplemented!() | ||||||
// HelpVariants::DotCommand => self.dot_command_help( helper, dictionary ), | ||||||
} | ||||||
} | ||||||
|
||||||
// .help | ||||||
fn general_help( &self, helper : &HelpGeneratorFn, dictionary : &mut Dictionary ) | ||||||
fn general_help( &self, helper : &HelpGeneratorFn, dictionary : &mut Dictionary, order : Option< Vec< String > > ) | ||||||
{ | ||||||
let phrase = "help".to_string(); | ||||||
|
||||||
|
@@ -205,18 +231,23 @@ pub( crate ) mod private | |||||
} | ||||||
else | ||||||
{ | ||||||
let mut options = HelpGeneratorOptions::former() | ||||||
.command_prefix( "." ) | ||||||
.description_detailing( LevelOfDetail::Simple ) | ||||||
.subject_detailing( LevelOfDetail::Simple ) | ||||||
.property_detailing( LevelOfDetail::Simple ) | ||||||
.with_nature_order( order.is_some() ); | ||||||
if let Some(order) = order.as_ref() | ||||||
{ | ||||||
options = options.order( order.clone() ); | ||||||
} | ||||||
println! | ||||||
( | ||||||
"Help command\n\n{text}", | ||||||
text = generator.exec | ||||||
( | ||||||
&grammar, | ||||||
HelpGeneratorOptions::former() | ||||||
.command_prefix( "." ) | ||||||
.description_detailing( LevelOfDetail::Simple ) | ||||||
.subject_detailing( LevelOfDetail::Simple ) | ||||||
.property_detailing( LevelOfDetail::Simple ) | ||||||
.form() | ||||||
options.form() | ||||||
) | ||||||
); | ||||||
} | ||||||
|
@@ -240,7 +271,7 @@ pub( crate ) mod private | |||||
} | ||||||
|
||||||
// .help command_name | ||||||
fn subject_command_help( &self, helper : &HelpGeneratorFn, dictionary : &mut Dictionary ) | ||||||
fn subject_command_help( &self, helper : &HelpGeneratorFn, dictionary : &mut Dictionary, order : Option< Vec< String > > ) | ||||||
{ | ||||||
let phrase = "help".to_string(); | ||||||
|
||||||
|
@@ -260,15 +291,19 @@ pub( crate ) mod private | |||||
let command = o.args.get_owned::< String >( 0 ).unwrap(); | ||||||
let cmd = grammar.commands.get( &command ).ok_or_else( || anyhow!( "Can not found help for command `{command}`" ) )?; | ||||||
|
||||||
let args = HelpGeneratorOptions::former() | ||||||
let mut args = HelpGeneratorOptions::former() | ||||||
.command_prefix( "." ) | ||||||
.for_commands([ cmd ]) | ||||||
.description_detailing( LevelOfDetail::Detailed ) | ||||||
.subject_detailing( LevelOfDetail::Simple ) | ||||||
.property_detailing( LevelOfDetail::Simple ) | ||||||
.with_footer( true ) | ||||||
.form(); | ||||||
let text = generator.exec( &grammar, args ); | ||||||
.with_nature_order( order.is_some() ); | ||||||
if let Some(order) = order.as_ref() | ||||||
{ | ||||||
args = args.order( order.clone() ); | ||||||
} | ||||||
let text = generator.exec( &grammar, args.form() ); | ||||||
|
||||||
println!( "Help command\n\n{text}" ); | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
fn main() | ||
{ | ||
use wca::{ Type, VerifiedCommand }; | ||
|
||
let ca = wca::CommandsAggregator::former() | ||
.command( "c" ) | ||
.hint( "c" ) | ||
.property( "c-property" ).kind( Type::String ).optional( true ).end() | ||
.property( "b-property" ).kind( Type::String ).optional( true ).end() | ||
.property( "a-property" ).kind( Type::String ).optional( true ).end() | ||
.routine( | o : VerifiedCommand | { println!("c") } ) | ||
.end() | ||
.command( "b" ) | ||
.hint( "b" ) | ||
.property( "b-property" ).kind( Type::String ).optional( true ).end() | ||
.routine( | o : VerifiedCommand | { println!("b") } ) | ||
.end() | ||
.command( "a" ) | ||
.hint( "a" ) | ||
.property( "a-property" ).kind( Type::String ).optional( true ).end() | ||
.routine( | o : VerifiedCommand | { println!("a") } ) | ||
.end() | ||
.with_nature_sort( false ) | ||
.perform(); | ||
|
||
let args = std::env::args().skip( 1 ).collect::< Vec< String > >(); | ||
ca.perform( args ).unwrap(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
fn main() | ||
{ | ||
use wca::{ Type, VerifiedCommand }; | ||
|
||
let ca = wca::CommandsAggregator::former() | ||
.command( "c" ) | ||
.hint( "c" ) | ||
.property( "c-property" ).kind( Type::String ).optional( true ).end() | ||
.property( "b-property" ).kind( Type::String ).optional( true ).end() | ||
.property( "a-property" ).kind( Type::String ).optional( true ).end() | ||
.routine( | o : VerifiedCommand | { println!("c") } ) | ||
.end() | ||
.command( "b" ) | ||
.hint( "b" ) | ||
.property( "b-property" ).kind( Type::String ).optional( true ).end() | ||
.routine( | o : VerifiedCommand | { println!("b") } ) | ||
.end() | ||
.command( "a" ) | ||
.hint( "a" ) | ||
.property( "a-property" ).kind( Type::String ).optional( true ).end() | ||
.routine( | o : VerifiedCommand | { println!("a") } ) | ||
.end() | ||
.with_nature_sort( true ) | ||
.perform(); | ||
|
||
let args = std::env::args().skip( 1 ).collect::< Vec< String > >(); | ||
ca.perform( args ).unwrap(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use
enum
instead ofbool
, can't we?