Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1dd1fcf

Browse files
committed
feat(CLI): field cursor complete and untested
Tests just need to be run, and of course, the impementation might need fixing. Related to #64
1 parent c9c3ad0 commit 1dd1fcf

2 files changed

Lines changed: 80 additions & 2 deletions

File tree

src/rust/cli/cmn.rs

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,72 @@ use std::io::{Write, Read, stdout};
1313

1414
use std::default::Default;
1515

16-
const FIELD_SEP: &'static str = ".";
16+
const FIELD_SEP: char = 'c';
1717

1818
#[derive(Clone, Default)]
1919
pub struct FieldCursor(Vec<String>);
2020

2121
impl ToString for FieldCursor {
2222
fn to_string(&self) -> String {
23-
String::new()
23+
self.0.connect(".")
2424
}
2525
}
2626

2727
impl 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)]
201273
pub 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

209282
impl 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),

src/rust/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ mod test_cli {
165165

166166
assert_eq!(c.to_string(), "");
167167
assert_eq!(c.num_fields(), 0);
168+
assert!(c.set("").is_err());
168169
assert!(c.set(".").is_ok());
169170
assert!(c.set("..").is_err());
170171
assert_eq!(c.num_fields(), 0);
@@ -190,5 +191,8 @@ mod test_cli {
190191
assert!(c.set(".one.two.three...beer").is_ok());
191192
assert_eq!(c.num_fields(), 2);
192193
assert_eq!(c.to_string(), "one.beer");
194+
assert!(c.set("one.two.three...").is_ok());
195+
assert_eq!(c.num_fields(), 3);
196+
assert_eq!(c.to_string(), "one.beer.one");
193197
}
194198
}

0 commit comments

Comments
 (0)