Skip to content

Commit 8e6cdc9

Browse files
author
Matthias Wahl
committed
Add custom de-/serializers to Method
in order to serialize it to string.
1 parent 18b86df commit 8e6cdc9

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/method.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use serde::de::{Error as DeError, Unexpected};
2+
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
13
use std::fmt::{self, Display};
24
use std::str::FromStr;
35

@@ -50,6 +52,44 @@ impl Method {
5052
}
5153
}
5254

55+
struct MethodVisitor;
56+
57+
impl<'de> Visitor<'de> for MethodVisitor {
58+
type Value = Method;
59+
60+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
61+
write!(formatter, "a HTTP method &str")
62+
}
63+
64+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
65+
where
66+
E: DeError,
67+
{
68+
match Method::from_str(v) {
69+
Ok(method) => Ok(method),
70+
Err(_) => Err(DeError::invalid_value(Unexpected::Str(v), &self)),
71+
}
72+
}
73+
}
74+
75+
impl<'de> Deserialize<'de> for Method {
76+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77+
where
78+
D: Deserializer<'de>,
79+
{
80+
deserializer.deserialize_str(MethodVisitor)
81+
}
82+
}
83+
84+
impl Serialize for Method {
85+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86+
where
87+
S: Serializer,
88+
{
89+
serializer.serialize_str(&self.to_string())
90+
}
91+
}
92+
5393
impl Display for Method {
5494
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5595
match self {
@@ -108,3 +148,20 @@ impl AsRef<str> for Method {
108148
}
109149
}
110150
}
151+
152+
#[cfg(test)]
153+
mod test {
154+
use super::Method;
155+
156+
#[test]
157+
fn serde() -> Result<(), serde_json::Error> {
158+
assert_eq!(Method::Get, serde_json::from_str("\"GET\"")?);
159+
assert_eq!(Some("PATCH"), serde_json::to_value(Method::Patch)?.as_str());
160+
Ok(())
161+
}
162+
#[test]
163+
fn serde_fail() -> Result<(), serde_json::Error> {
164+
serde_json::from_str::<Method>("\"ABC\"").expect_err("Did deserialize from invalid string");
165+
Ok(())
166+
}
167+
}

0 commit comments

Comments
 (0)