mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
option_parser: Remove surrounding space
We remove whitespace from `Tuple` input to allow input of the form " key@value ". Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de> On-behalf-of: SAP pascal.scholz@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
d054a38600
commit
e32f8846c2
@@ -498,17 +498,19 @@ impl<S: Parseable, T: TupleValue> Parseable for Tuple<S, T> {
|
|||||||
let mut in_quotes = false;
|
let mut in_quotes = false;
|
||||||
let mut last_idx = 0;
|
let mut last_idx = 0;
|
||||||
let mut first_val = None;
|
let mut first_val = None;
|
||||||
for (idx, c) in tuple.as_bytes().iter().enumerate() {
|
let trimmed = tuple.trim();
|
||||||
|
for (idx, c) in trimmed.as_bytes().iter().enumerate() {
|
||||||
match c {
|
match c {
|
||||||
b'"' => in_quotes = !in_quotes,
|
b'"' => in_quotes = !in_quotes,
|
||||||
b'@' if !in_quotes => {
|
b'@' if !in_quotes => {
|
||||||
if last_idx != 0 {
|
if last_idx != 0 {
|
||||||
return Err(TupleError::InvalidValue((*tuple).to_string()));
|
return Err(TupleError::InvalidValue((*trimmed).to_string()));
|
||||||
}
|
}
|
||||||
first_val = if tuple[last_idx..idx].is_empty() {
|
let key = &trimmed[last_idx..idx];
|
||||||
return Err(TupleError::EmptyKey((*tuple).to_string()));
|
first_val = if key.is_empty() {
|
||||||
|
return Err(TupleError::EmptyKey((*trimmed).to_string()));
|
||||||
} else {
|
} else {
|
||||||
Some(&tuple[last_idx..idx])
|
Some(key)
|
||||||
};
|
};
|
||||||
last_idx = idx + 1;
|
last_idx = idx + 1;
|
||||||
}
|
}
|
||||||
@@ -516,10 +518,10 @@ impl<S: Parseable, T: TupleValue> Parseable for Tuple<S, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let item1 = <S as Parseable>::from_str(
|
let item1 = <S as Parseable>::from_str(
|
||||||
first_val.ok_or(TupleError::InvalidValue((*tuple).to_string()))?,
|
first_val.ok_or(TupleError::InvalidValue((*trimmed).to_string()))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| TupleError::InvalidValue(first_val.unwrap().to_owned()))?;
|
.map_err(|_| TupleError::InvalidValue(first_val.unwrap().to_owned()))?;
|
||||||
let item2: T = TupleValue::parse_value(&tuple[last_idx..])?;
|
let item2: T = TupleValue::parse_value(&trimmed[last_idx..])?;
|
||||||
Ok(Tuple(item1, item2))
|
Ok(Tuple(item1, item2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,6 +864,65 @@ mod unit_tests {
|
|||||||
assert_eq!(t, Tuple("foo".to_owned(), vec![42]));
|
assert_eq!(t, Tuple("foo".to_owned(), vec![42]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_allowed_whitespace() {
|
||||||
|
let t = Tuple::<String, u64>::from_str(" foo@42").unwrap();
|
||||||
|
assert_eq!(t, Tuple("foo".to_owned(), 42));
|
||||||
|
let t = Tuple::<String, u64>::from_str("foo@42 ").unwrap();
|
||||||
|
assert_eq!(t, Tuple("foo".to_owned(), 42));
|
||||||
|
let t = Tuple::<String, u64>::from_str(" foo@42 ").unwrap();
|
||||||
|
assert_eq!(t, Tuple("foo".to_owned(), 42));
|
||||||
|
let t = Tuple::<u64, u64>::from_str(" 5@42 ").unwrap();
|
||||||
|
assert_eq!(t, Tuple(5, 42));
|
||||||
|
// Still a valid string as key, even with trailing whitespace
|
||||||
|
let t = Tuple::<String, u64>::from_str(" foo @42 ").unwrap();
|
||||||
|
assert_eq!(t, Tuple("foo ".to_owned(), 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_whitespace_surrounding_delimiter_fails() {
|
||||||
|
let e = Tuple::<String, u64>::from_str("foo@ 42").unwrap_err();
|
||||||
|
assert!(
|
||||||
|
matches!(e, TupleError::InvalidInteger(_)),
|
||||||
|
"Expected \"ParseInt\"; got \"{e:?}\"",
|
||||||
|
);
|
||||||
|
let expected_value = "42 ";
|
||||||
|
let e = Tuple::<u64, Vec<u64>>::from_str("42 @[]").unwrap_err();
|
||||||
|
assert!(
|
||||||
|
matches!(e, TupleError::InvalidValue(ref s) if s == expected_value),
|
||||||
|
"Expected \"{:?}\"; got \"{e:?}\"",
|
||||||
|
TupleError::InvalidValue(expected_value.to_string()),
|
||||||
|
);
|
||||||
|
// We abuse of the fact that space can be converted to a valid string as long as the
|
||||||
|
// string isn't empty. We use this to check the correct error for tuple value parsing.
|
||||||
|
let e = Tuple::<String, u64>::from_str(" foo @ 42 ").unwrap_err();
|
||||||
|
assert!(
|
||||||
|
matches!(e, TupleError::InvalidInteger(_)),
|
||||||
|
"Expected \"ParseInt\"; got \"{e:?}\"",
|
||||||
|
);
|
||||||
|
// Cannot parse the space into a list
|
||||||
|
let expected_value = "";
|
||||||
|
let e = Tuple::<u64, Vec<u64>>::from_str("42@ []").unwrap_err();
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
e,
|
||||||
|
TupleError::InvalidIntegerList(
|
||||||
|
IntegerListParseError::InvalidValue(ref s),
|
||||||
|
) if s == expected_value
|
||||||
|
),
|
||||||
|
"Expected \"{:?}\"; got \"{e:?}\"",
|
||||||
|
TupleError::InvalidIntegerList(IntegerListParseError::InvalidValue(
|
||||||
|
expected_value.to_string()
|
||||||
|
),)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_list_single_pair() {
|
||||||
|
let t = TupleList::<String, u64>::from_str("[foo@42]").unwrap();
|
||||||
|
assert_eq!(t, TupleList(vec![Tuple("foo".to_owned(), 42)]));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tuple_list_multiple_pairs() {
|
fn test_tuple_list_multiple_pairs() {
|
||||||
let t = TupleList::<String, Vec<u64>>::from_str("[a@[1,2],b@[3,4]]").unwrap();
|
let t = TupleList::<String, Vec<u64>>::from_str("[a@[1,2],b@[3,4]]").unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user