diff --git a/src/network/telegram_response.rs b/src/network/telegram_response.rs index 05e7acb7..a3c77b4e 100644 --- a/src/network/telegram_response.rs +++ b/src/network/telegram_response.rs @@ -2,6 +2,7 @@ use reqwest::StatusCode; use crate::{ requests::ResponseResult, types::ResponseParameters, RequestError, + types::{True, False} }; #[derive(Deserialize)] @@ -10,14 +11,14 @@ pub enum TelegramResponse { Ok { /// A dummy field. Used only for deserialization. #[allow(dead_code)] - ok: bool, // TODO: True type + ok: True, result: R, }, Err { /// A dummy field. Used only for deserialization. #[allow(dead_code)] - ok: bool, // TODO: False type + ok: False, description: String, error_code: u16, 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..78299be1 --- /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 for False { + type Error = (); + + fn try_from(value: bool) -> Result { + #[allow(clippy::match_bool)] + match value { + true => Err(()), + false => Ok(False), + } + } +} + +impl<'de> Deserialize<'de> for False { + fn deserialize(deserializer: D) -> Result + 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(self, value: bool) -> Result + 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(&self, serializer: S) -> Result + where + S: Serializer + { + serializer.serialize_bool(false) + } +} + +#[cfg(test)] +mod tests { + use serde_json::{from_str, to_string}; + + use super::False; + + #[test] + fn unit_false_de() { + let json = "false"; + let expected = False; + let actual = from_str(json).unwrap(); + assert_eq!(expected, actual); + } + + #[test] + fn unit_false_se() { + let actual = to_string(&False).unwrap(); + let expected = "false"; + assert_eq!(expected, actual); + } +}