dovemail 0.0.1

Use Microsoft's PNP CLI with email clients.
Documentation
//! Type definitions for deserializing JSON which is well-formed but possibly invalid.

#[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)
    }
}