1extern crate hex;
23extern crate serde;
24
25use std::fmt;
26use std::marker::PhantomData;
27use hex::{FromHex, FromHexError, ToHex};
28use serde::{de, Deserializer, Serializer};
29use serde::de::Visitor;
30
31pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
33where
34 S: Serializer,
35 T: AsRef<[u8]>,
36{
37 let mut output = String::new();
38 value.write_hex(&mut output).expect("Failed to write hex");
39 serializer.serialize_str(&output)
40}
41
42pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
44where
45 D: Deserializer<'de>,
46 T: FromHex<Error = FromHexError>,
47{
48 struct HexVisitor<T>(PhantomData<T>);
49
50 impl<'de, T> Visitor<'de> for HexVisitor<T>
51 where
52 T: FromHex<Error = FromHexError>,
53 {
54 type Value = T;
55
56 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
57 write!(formatter, "hex ASCII text")
58 }
59
60 fn visit_str<E>(self, v: &str) -> Result<T, E>
61 where
62 E: de::Error,
63 {
64 T::from_hex(v).map_err(|e| match e {
65 FromHexError::InvalidHexCharacter { c, index } => E::invalid_value(
66 de::Unexpected::Char(c),
67 &format!("Unexpected character {:?} as position {}", c, index).as_str(),
68 ),
69 FromHexError::InvalidStringLength => {
70 E::invalid_length(v.len(), &"Unexpected length of hex string")
71 }
72 FromHexError::OddLength => E::invalid_length(v.len(), &"Odd length of hex string"),
73 })
74 }
75 }
76
77 deserializer.deserialize_str(HexVisitor(PhantomData))
78}