radicle: safe Reaction construction
The Reaction type needs to ensure that the `char` stored for its value meets certain requirements -- via its `new` constructor. To ensure Reaction is always constructed correctly, the `pub` accessor is removed, and the Deserialize implementation is implemented by hand -- as opposed to using derive. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
0337574750
commit
de8e92d48c
|
|
@ -36,10 +36,10 @@ pub enum ReactionError {
|
||||||
InvalidReaction,
|
InvalidReaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Reaction {
|
pub struct Reaction {
|
||||||
pub emoji: char,
|
emoji: char,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reaction {
|
impl Reaction {
|
||||||
|
|
@ -51,6 +51,46 @@ impl Reaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Reaction {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
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<E>(self, v: char) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Reaction::new(v).map_err(|e| E::custom(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Reaction::from_str(v).map_err(|e| E::custom(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
|
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 {
|
impl FromStr for Reaction {
|
||||||
type Err = ReactionError;
|
type Err = ReactionError;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue