diff --git a/radicle/src/cob/common.rs b/radicle/src/cob/common.rs index 88c79b93..d1acc28b 100644 --- a/radicle/src/cob/common.rs +++ b/radicle/src/cob/common.rs @@ -36,10 +36,10 @@ pub enum ReactionError { InvalidReaction, } -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize)] #[serde(transparent)] pub struct Reaction { - pub emoji: char, + emoji: char, } impl Reaction { @@ -51,6 +51,46 @@ impl Reaction { } } +impl<'de> Deserialize<'de> for Reaction { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct ReactionVisitor; + + impl<'de> serde::de::Visitor<'de> for ReactionVisitor { + type Value = Reaction; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a reaction emoji") + } + + fn visit_char(self, v: char) -> Result + where + E: serde::de::Error, + { + Reaction::new(v).map_err(|e| E::custom(e.to_string())) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Reaction::from_str(v).map_err(|e| E::custom(e.to_string())) + } + + fn visit_string(self, v: String) -> Result + where + E: serde::de::Error, + { + Reaction::from_str(&v).map_err(|e| E::custom(e.to_string())) + } + } + + deserializer.deserialize_char(ReactionVisitor) + } +} + impl FromStr for Reaction { type Err = ReactionError;