1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![feature(specialization)]

use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// This trait is impl for every types
///
/// If type implement `Serialize` then `maybe_serialize` return `Serialize::serialize` value with `Some`
///
/// Otherwise if type doesn't implement `Serialize` then `maybe_serialize` return just `None`
pub trait MaybeSer {
    fn maybe_serialize<S>(&self, serializer: S) -> Option<Result<S::Ok, S::Error>>
    where
        S: Serializer;
}

/// This trait is impl for every types
///
/// If type implement `Deserialize` then `maybe_deserialize` return `Deserialize::deserialize` value with `Some`
///
/// Otherwise if type doesn't implement `Deserialize` then `maybe_deserialize` return just `None`
pub trait MaybeDe<'de>: Sized {
    fn maybe_deserialize<D>(deserializer: D) -> Option<Result<Self, D::Error>>
    where
        D: Deserializer<'de>;
}

/// Always return `None`
impl<T> MaybeSer for T {
    default fn maybe_serialize<S>(
        &self,
        _serializer: S,
    ) -> Option<Result<<S as Serializer>::Ok, <S as Serializer>::Error>>
    where
        S: Serializer,
    {
        None
    }
}

/// Always return `None`
impl<'de, T> MaybeDe<'de> for T {
    default fn maybe_deserialize<D>(
        _deserializer: D,
    ) -> Option<Result<Self, <D as Deserializer<'de>>::Error>>
    where
        D: Deserializer<'de>,
    {
        None
    }
}

/// Always return `Some`
impl<T> MaybeSer for T
where
    T: Serialize,
{
    fn maybe_serialize<S>(
        &self,
        serializer: S,
    ) -> Option<Result<<S as Serializer>::Ok, <S as Serializer>::Error>>
    where
        S: Serializer,
    {
        Some(self.serialize(serializer))
    }
}

/// Always return `Some`
impl<'de, T> MaybeDe<'de> for T
where
    T: Deserialize<'de>,
{
    fn maybe_deserialize<D>(
        deserializer: D,
    ) -> Option<Result<Self, <D as Deserializer<'de>>::Error>>
    where
        D: Deserializer<'de>,
    {
        Some(T::deserialize(deserializer))
    }
}

#[cfg(test)]
mod tests {
    use super::{MaybeDe, MaybeSer};
    use serde_derive::{Deserialize, Serialize};
    use serde_json::{de::StrRead, Deserializer, Result, Serializer};

    fn ser_fn<V>(val: &V) -> Option<Result<()>>
    where
        V: MaybeSer,
    {
        let mut buf = Vec::new();
        val.maybe_serialize(&mut Serializer::new(&mut buf))
    }

    fn de_fn<'de, V>(text: &'de str) -> Option<Result<V>>
    where
        V: MaybeDe<'de>,
    {
        V::maybe_deserialize(&mut Deserializer::new(StrRead::new(text)))
    }

    #[test]
    fn serde_none() {
        struct NoneSerde(i32);

        assert!(ser_fn(&NoneSerde(123)).is_none());
        assert!(de_fn::<NoneSerde>("123").is_none());
    }

    #[test]
    fn serde_some() {
        #[derive(Serialize, Deserialize)]
        struct SomeSerde(i32);

        assert!(ser_fn(&SomeSerde(123)).is_some());
        assert_eq!(de_fn::<SomeSerde>("123").unwrap().unwrap().0, 123);
    }
}