Skip to content
This repository was archived by the owner on Nov 30, 2022. It is now read-only.

Commit bc61e91

Browse files
committed
serde: remove allocation from the human-readable deserializer
1 parent ad8791f commit bc61e91

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/serde_macros.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,38 @@ macro_rules! serde_impl(
1717

1818
impl<'de> ::serde::Deserialize<'de> for $t {
1919
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<$t, D::Error> {
20-
use ::serde::de::Error;
2120
use hex::FromHex;
2221

2322
if d.is_human_readable() {
24-
let sl: String = ::serde::Deserialize::deserialize(d)?;
25-
$t::from_hex(&sl).map_err(D::Error::custom)
23+
struct HexVisitor;
24+
25+
impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
26+
type Value = $t;
27+
28+
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
29+
formatter.write_str("an ASCII hex string")
30+
}
31+
32+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
33+
where
34+
E: ::serde::de::Error,
35+
{
36+
if let Ok(hex) = ::std::str::from_utf8(v) {
37+
$t::from_hex(hex).map_err(E::custom)
38+
} else {
39+
return Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self));
40+
}
41+
}
42+
43+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
44+
where
45+
E: ::serde::de::Error,
46+
{
47+
$t::from_hex(v).map_err(E::custom)
48+
}
49+
}
50+
51+
d.deserialize_str(HexVisitor)
2652
} else {
2753
struct BytesVisitor;
2854

0 commit comments

Comments
 (0)