@@ -13,19 +13,72 @@ use std::io::{Write, Read, stdout};
1313
1414use std:: default:: Default ;
1515
16- const FIELD_SEP : & ' static str = "." ;
16+ const FIELD_SEP : char = 'c' ;
1717
1818#[ derive( Clone , Default ) ]
1919pub struct FieldCursor ( Vec < String > ) ;
2020
2121impl ToString for FieldCursor {
2222 fn to_string ( & self ) -> String {
23- String :: new ( )
23+ self . 0 . connect ( "." )
2424 }
2525}
2626
2727impl FieldCursor {
2828 pub fn set ( & mut self , value : & str ) -> Result < ( ) , CLIError > {
29+ let mut first_is_field_sep = false ;
30+ let mut char_count: usize = 0 ;
31+ let mut last_c = FIELD_SEP ;
32+ let mut num_conscutive_field_seps = 0 ;
33+
34+ let mut field = String :: new ( ) ;
35+ let mut fields = self . 0 . clone ( ) ;
36+
37+ let push_field = |fields : & mut Vec < String > , field : & mut String | {
38+ if field. len ( ) > 0 {
39+ fields. push ( field. clone ( ) ) ;
40+ field. truncate ( 0 ) ;
41+ }
42+ } ;
43+
44+ for ( cid, c) in value. chars ( ) . enumerate ( ) {
45+ char_count = cid + 1 ;
46+
47+ if cid == 0 && c == FIELD_SEP {
48+ first_is_field_sep = true ;
49+ }
50+ if c == FIELD_SEP {
51+ num_conscutive_field_seps += 1 ;
52+ if last_c == FIELD_SEP {
53+ if fields. pop ( ) . is_none ( ) {
54+ return Err ( CLIError :: Field ( FieldError :: PopOnEmpty ) )
55+ }
56+ } else {
57+ push_field ( & mut fields, & mut field) ;
58+ }
59+ } else {
60+ num_conscutive_field_seps = 0 ;
61+ if cid == 1 {
62+ if first_is_field_sep {
63+ fields. truncate ( 0 ) ;
64+ }
65+ }
66+ field. push ( c) ;
67+ }
68+
69+ last_c = c;
70+ }
71+
72+ push_field ( & mut fields, & mut field) ;
73+
74+ if char_count == 1 && first_is_field_sep {
75+ fields. truncate ( 0 ) ;
76+ }
77+ if char_count > 1 && num_conscutive_field_seps == 1 {
78+ return Err ( CLIError :: Field ( FieldError :: TrailingFieldSep ) )
79+ }
80+
81+ self . 0 = fields;
2982 Ok ( ( ) )
3083 }
3184
@@ -197,20 +250,41 @@ impl fmt::Display for InputError {
197250 }
198251}
199252
253+ #[ derive( Debug ) ]
254+ pub enum FieldError {
255+ PopOnEmpty ,
256+ TrailingFieldSep ,
257+ }
258+
259+
260+ impl fmt:: Display for FieldError {
261+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
262+ match * self {
263+ FieldError :: PopOnEmpty
264+ => writeln ! ( f, "Cannot move up on empty field cursor" ) ,
265+ FieldError :: TrailingFieldSep
266+ => writeln ! ( f, "Single field separator may not be last character" ) ,
267+ }
268+ }
269+ }
270+
271+
200272#[ derive( Debug ) ]
201273pub enum CLIError {
202274 Configuration ( ConfigurationError ) ,
203275 ParseError ( ( & ' static str , & ' static str , String , String ) ) ,
204276 UnknownParameter ( String ) ,
205277 InvalidKeyValueSyntax ( String ) ,
206278 Input ( InputError ) ,
279+ Field ( FieldError ) ,
207280}
208281
209282impl fmt:: Display for CLIError {
210283 fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
211284 match * self {
212285 CLIError :: Configuration ( ref err) => write ! ( f, "Configuration -> {}" , err) ,
213286 CLIError :: Input ( ref err) => write ! ( f, "Input -> {}" , err) ,
287+ CLIError :: Field ( ref err) => write ! ( f, "Field -> {}" , err) ,
214288 CLIError :: ParseError ( ( arg_name, type_name, ref value, ref err_desc) )
215289 => writeln ! ( f, "Failed to parse argument '{}' with value '{}' as {} with error: {}" ,
216290 arg_name, value, type_name, err_desc) ,
0 commit comments