pub( crate ) mod private { pub use wtools::error::*; pub use wtools::string::parse_request; pub use wtools::string::parse_request::OpType; pub use wtools::former::Former; use std::collections::HashMap; /// /// Instruction handle. /// #[ derive( Debug, Default, PartialEq ) ] pub struct Instruction { /// Error of Instruction forming. pub err : Option< BasicError >, /// Name of command pub command_name : String, /// Subject. pub subject : String, /// Properties map. pub properties_map : HashMap>, } /// /// Parameters for parsing instructions. /// #[ derive( Debug ) ] #[ derive( Former ) ] #[ perform( fn parse( &self ) -> Instruction ) ] pub struct InstructionParseParams<'a> { #[ default( "" ) ] instruction : &'a str, properties_map : Option>>, #[ 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> { /// Set not default builder field `properties_map`. pub fn properties_map( mut self, properties_map : HashMap> ) -> InstructionParseParams<'a> { self.properties_map = Some( properties_map ); self } } /// /// Instruction behaviour. /// pub trait InstructionParseParamsAdapter { /// Print info about valid command format. fn about_command_format( &self ) -> &'static str; /// Check that command name is valid. fn command_name_is_valid( &self, command_name : &str ) -> bool; /// Parse instruction from string slice. fn parse_str( &self ) -> Instruction; /// Main parser. 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::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 /* dead code to delete */ { } 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() } } // /// /// Get instruction parser builder. /// pub fn instruction_parse<'a>() -> InstructionParseParamsFormer<'a> { InstructionParseParams::former() } } /// Protected namespace of the module. pub mod protected { // use super::private as i; pub use super::private::Instruction; pub use super::private::InstructionParseParams; pub use super::private::InstructionParseParamsAdapter; pub use super::private::instruction_parse; } pub use protected::*; /// Exposed namespace of the module. pub mod exposed { // use super::private as i; pub use super::private::InstructionParseParamsAdapter; pub use super::private::instruction_parse; } /// Namespace of the module to include with `use module::*`. pub mod prelude { // use super::private as i; pub use super::private::InstructionParseParamsAdapter; }