Skip to content

Commit ad513b5

Browse files
author
Matthias Wahl
committed
Add custom de-/serializers to Version
in order to serialize it to string.
1 parent 2dfe020 commit ad513b5

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/version.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use serde::{de::Error, de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
12
/// The version of the HTTP protocol in use.
23
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
34
#[non_exhaustive]
@@ -18,6 +19,55 @@ pub enum Version {
1819
Http3_0,
1920
}
2021

22+
impl Serialize for Version {
23+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24+
where
25+
S: Serializer,
26+
{
27+
serializer.serialize_str(&self.to_string())
28+
}
29+
}
30+
31+
struct VersionVisitor;
32+
33+
impl<'de> Visitor<'de> for VersionVisitor {
34+
type Value = Version;
35+
36+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
37+
write!(formatter, "a HTTP version as &str")
38+
}
39+
40+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
41+
where
42+
E: Error,
43+
{
44+
match v {
45+
"HTTP/0.9" => Ok(Version::Http0_9),
46+
"HTTP/1.0" => Ok(Version::Http1_0),
47+
"HTTP/1.1" => Ok(Version::Http1_1),
48+
"HTTP/2" => Ok(Version::Http2_0),
49+
"HTTP/3" => Ok(Version::Http3_0),
50+
_ => Err(Error::invalid_value(serde::de::Unexpected::Str(v), &self)),
51+
}
52+
}
53+
54+
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
55+
where
56+
E: Error,
57+
{
58+
self.visit_str(&v)
59+
}
60+
}
61+
62+
impl<'de> Deserialize<'de> for Version {
63+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64+
where
65+
D: Deserializer<'de>,
66+
{
67+
deserializer.deserialize_str(VersionVisitor)
68+
}
69+
}
70+
2171
impl std::fmt::Display for Version {
2272
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2373
f.write_str(match self {
@@ -54,4 +104,11 @@ mod test {
54104
assert!(Http1_1 > Http1_0);
55105
assert!(Http1_0 > Http0_9);
56106
}
107+
108+
#[test]
109+
fn serde() -> Result<(), serde_json::Error> {
110+
assert_eq!("\"HTTP/3\"", serde_json::to_string(&Version::Http3_0)?);
111+
assert_eq!(Version::Http1_1, serde_json::from_str("\"HTTP/1.1\"")?);
112+
Ok(())
113+
}
57114
}

0 commit comments

Comments
 (0)