#[derive(serde::Deserialize, Debug, PartialEq)]
#[serde(untagged)]
pub enum SingleOrList<T> {
List(Vec<MaybeValid<T>>),
Single(T),
}
#[derive(serde::Deserialize, Debug, PartialEq)]
#[serde(untagged)]
pub enum MaybeValid<T> {
Valid(T),
Invalid(serde_json::Value),
}
impl<T> SingleOrList<T> {
pub fn into_vec(self) -> Vec<MaybeValid<T>> {
match self {
SingleOrList::List(x) => x,
SingleOrList::Single(x) => vec![MaybeValid::Valid(x)],
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(serde::Deserialize, Debug, PartialEq)]
struct Foo {
bar: u32,
}
#[test]
fn test_single_valid() {
let actual: MaybeValid<Foo> = serde_json::from_str(r#"{"bar": 5}"#).unwrap();
let expected = MaybeValid::Valid(Foo { bar: 5 });
assert_eq!(actual, expected)
}
#[test]
fn test_single_invalid() {
let actual: MaybeValid<Foo> = serde_json::from_str(r#"{"not": "valid"}"#).unwrap();
let expected = MaybeValid::Invalid(serde_json::json!({"not": "valid"}));
assert_eq!(actual, expected)
}
#[test]
fn test_list() {
let data = r#"[{"bar": 4}, {"i am": "invalid"}, {"bar": 3}]"#;
let actual: SingleOrList<Foo> = serde_json::from_str(data).unwrap();
let expected = SingleOrList::List(vec![
MaybeValid::Valid(Foo { bar: 4 }),
MaybeValid::Invalid(serde_json::json!({"i am": "invalid"})),
MaybeValid::Valid(Foo { bar: 3 }),
]);
assert_eq!(actual, expected)
}
}