diff --git a/src/types/mod.rs b/src/types/mod.rs index e1f08e4f..eadb5942 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -47,6 +47,7 @@ pub use sticker::*; pub use sticker_set::*; pub use successful_payment::*; pub use unit_true::*; +pub use unit_false::*; pub use update::*; pub use user::*; pub use user_profile_photos::*; @@ -130,6 +131,7 @@ mod shipping_query; mod sticker; mod sticker_set; mod successful_payment; +mod unit_false; mod unit_true; mod update; mod user; diff --git a/src/types/unit_false.rs b/src/types/unit_false.rs new file mode 100644 index 00000000..2ac0f793 --- /dev/null +++ b/src/types/unit_false.rs @@ -0,0 +1,78 @@ +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::de::Visitor; + +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct False; + +impl std::convert::TryFrom<bool> for False { + type Error = (); + + fn try_from(value: bool) -> Result<Self, Self::Error> { + #[allow(clippy::match_bool)] + match value { + true => Err(()), + false => Ok(False), + } + } +} + +impl<'de> Deserialize<'de> for False { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de> + { + deserializer.deserialize_bool(FalseVisitor) + } +} + +struct FalseVisitor; + +impl<'de> Visitor<'de> for FalseVisitor { + type Value = False; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "bool, equal to `false`") + } + + fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + #[allow(clippy::match_bool)] + match value { + true => Err(E::custom("expected `false`, found `true`")), + false => Ok(False) + } + } +} + +impl Serialize for False { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer + { + serializer.serialize_bool(false) + } +} + +#[cfg(test)] +mod tests { + use serde_json::{from_str, to_string}; + + use super::False; + + #[test] + fn unit_true_de() { + let json = "false"; + let expected = False; + let actual = from_str(json).unwrap(); + assert_eq!(expected, actual); + } + + #[test] + fn unit_true_se() { + let actual = to_string(&False).unwrap(); + let expected = "false"; + assert_eq!(expected, actual); + } +}