hex_serde/
lib.rs

1//! Integration between hex and serde
2//!
3//! # Examples
4//!
5//! ```
6//! # extern crate hex_serde;
7//! # #[macro_use]
8//! # extern crate serde;
9//! # #[macro_use]
10//! # extern crate serde_derive;
11//! #[derive(Serialize, Deserialize)]
12//! struct Sha256(#[serde(with = "hex_serde")] [u8; 32]);
13//!
14//! #[derive(Serialize, Deserialize)]
15//! struct MyStruct {
16//!     #[serde(with = "hex_serde")] icecream: Vec<u8>,
17//!     count: u64,
18//! }
19//! # fn main() {}
20//! ```
21
22extern 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
31/// A serializer that first encodes the argument as a hex-string
32pub 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
42/// A deserializer that first encodes the argument as a hex-string
43pub 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}