pub( crate ) mod private
{
pub use wtools::error::*;
pub use wtools::string::parse;
pub use wtools::string::parse::OpType;
pub use former::Former;
use std::collections::HashMap;
#[ derive( Debug, Default, PartialEq ) ]
pub struct Instruction
{
pub err : Option< BasicError >,
pub command_name : String,
pub subject : String,
pub properties_map : HashMap<String, OpType<String>>,
}
#[ derive( Debug ) ]
#[ derive( Former ) ]
#[ perform( fn parse( &self ) -> Instruction ) ]
pub struct InstructionParseParams<'a>
{
#[ default( "" ) ]
instruction : &'a str,
properties_map : Option<HashMap<String, OpType<String>>>,
#[ default( true ) ]
properties_map_parsing : bool,
#[ default( true ) ]
several_values : bool,
#[ default( true ) ]
quoting : bool,
#[ default( false ) ]
unquoting : bool,
#[ default( false ) ]
subject_win_paths_maybe : bool,
}
impl<'a> InstructionParseParams<'a>
{
pub fn properties_map( mut self, properties_map : HashMap<String, OpType<String>> ) -> InstructionParseParams<'a>
{
self.properties_map = Some( properties_map );
self
}
}
pub trait InstructionParseParamsAdapter
{
fn about_command_format( &self ) -> &'static str;
fn command_name_is_valid( &self, command_name : &str ) -> bool;
fn parse_str( &self ) -> Instruction;
fn parse( &self ) -> Instruction;
}
impl <'a>InstructionParseParamsAdapter for InstructionParseParams<'a>
{
fn about_command_format( &self ) -> &'static str
{
r#"Command should start from a dot `.`.
Command can have a subject and properties.
Property is pair delimited by colon `:`.
For example: `.struct1 subject key1:val key2:val2`."#
}
fn command_name_is_valid( &self, command_name : &str ) -> bool
{
command_name.trim().starts_with( "." )
}
fn parse_str( &self ) -> Instruction
{
let mut result = Instruction::default();
let ( command_name, request ) = match self.instruction.split_once( " " )
{
Some( entries ) => entries,
None => ( self.instruction, "" ),
};
result.command_name = command_name.to_string();
if !self.command_name_is_valid( &result.command_name[ .. ] )
{
self.about_command_format();
result.err = Some( BasicError::new( "Invalid command" ) );
return result;
}
let request = parse::request_parse()
.src( request )
.several_values( self.several_values )
.quoting( self.quoting )
.unquoting( self.unquoting )
.subject_win_paths_maybe( self.subject_win_paths_maybe )
.perform();
if request.subjects.len() > 1
{
result.err = Some( BasicError::new( "Too many instructions" ) );
return result;
}
if self.properties_map_parsing
{
}
result.subject = request.subject.clone();
result.properties_map = request.map.clone();
if self.properties_map.is_some()
{
for ( key, value ) in self.properties_map.as_ref().unwrap().iter()
{
result.properties_map.insert( key.clone(), value.clone() );
}
}
result
}
fn parse( &self ) -> Instruction
{
self.parse_str()
}
}
pub fn instruction_parse<'a>() -> InstructionParseParamsFormer<'a>
{
InstructionParseParams::former()
}
}
pub mod protected
{
pub use super::private::Instruction;
pub use super::private::InstructionParseParams;
pub use super::private::InstructionParseParamsAdapter;
pub use super::private::instruction_parse;
}
pub use protected::*;
pub mod exposed
{
pub use super::private::InstructionParseParamsAdapter;
pub use super::private::instruction_parse;
}
pub mod prelude
{
pub use super::private::InstructionParseParamsAdapter;
}