mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-25 13:23:08 +00:00
serde_keyvalue: allow structs with default values to be left unspecified
Allow optional structs which members all have default values to have their values omitted. This is convenient when we want to specify a flag that can take optional extra arguments. BUG=b:217480278 TEST=cargo test -p serde_keyvalue Change-Id: If2920834f3221146439fc6b8ac54cd9cb215cb9e Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4596440 Commit-Queue: Alexandre Courbot <acourbot@chromium.org> Auto-Submit: Alexandre Courbot <acourbot@chromium.org> Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
parent
f1f0503070
commit
f8458abf49
1 changed files with 72 additions and 2 deletions
|
@ -771,7 +771,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut KeyValueDeserializer<'de> {
|
|||
Ok(val)
|
||||
}
|
||||
} else {
|
||||
Err(self.error_here(ErrorKind::ExpectedOpenBracket))
|
||||
// The `EmptyMapAccess` failing to parse means that this sequence must take arguments,
|
||||
// i.e. that an opening bracket is expected.
|
||||
visitor
|
||||
.visit_map(EmptyMapAccess)
|
||||
.map_err(|_| self.error_here(ErrorKind::ExpectedOpenBracket))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -818,7 +822,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut KeyValueDeserializer<'de> {
|
|||
if self.peek_char() == Some('[') {
|
||||
self.next_char();
|
||||
} else {
|
||||
return Err(self.error_here(ErrorKind::ExpectedOpenBracket));
|
||||
// The `EmptyMapAccess` failing to parse means that this struct must take
|
||||
// arguments, i.e. that an opening bracket is expected.
|
||||
return visitor
|
||||
.visit_map(EmptyMapAccess)
|
||||
.map_err(|_| self.error_here(ErrorKind::ExpectedOpenBracket));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1243,6 +1251,68 @@ mod tests {
|
|||
assert!(from_key_values::<TestStruct>(kv).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_optional_struct_with_default() {
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
struct DefaultStruct {
|
||||
#[serde(default)]
|
||||
param: u32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
struct TestStruct {
|
||||
flag: Option<DefaultStruct>,
|
||||
}
|
||||
|
||||
// Specify member explicitly
|
||||
let kv = "flag=[param=12]";
|
||||
let res: TestStruct = from_key_values(kv).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
TestStruct {
|
||||
flag: Some(DefaultStruct { param: 12 })
|
||||
}
|
||||
);
|
||||
|
||||
// No member specified, braces present.
|
||||
let kv = "flag=[]";
|
||||
let res: TestStruct = from_key_values(kv).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
TestStruct {
|
||||
flag: Some(DefaultStruct { param: 0 })
|
||||
}
|
||||
);
|
||||
|
||||
// No member specified, no braces.
|
||||
let kv = "flag=";
|
||||
let res: TestStruct = from_key_values(kv).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
TestStruct {
|
||||
flag: Some(DefaultStruct { param: 0 })
|
||||
}
|
||||
);
|
||||
|
||||
// No member specified, no braces, no equal sign.
|
||||
let kv = "flag";
|
||||
let res: TestStruct = from_key_values(kv).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
TestStruct {
|
||||
flag: Some(DefaultStruct { param: 0 })
|
||||
}
|
||||
);
|
||||
|
||||
// No closing brace.
|
||||
let kv = "flag=[";
|
||||
assert!(from_key_values::<TestStruct>(kv).is_err());
|
||||
|
||||
// No opening brace.
|
||||
let kv = "flag=]";
|
||||
assert!(from_key_values::<TestStruct>(kv).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_enum() {
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
|
|
Loading…
Reference in a new issue