//! Integration between hex and serde //! //! # Examples //! //! ``` //! # extern crate hex_serde; //! # #[macro_use] //! # extern crate serde; //! # #[macro_use] //! # extern crate serde_derive; //! #[derive(Serialize, Deserialize)] //! struct Sha256(#[serde(with = "hex_serde")] [u8; 32]); //! //! #[derive(Serialize, Deserialize)] //! struct MyStruct { //! #[serde(with = "hex_serde")] icecream: Vec, //! count: u64, //! } //! # fn main() {} //! ``` extern crate hex; extern crate serde; use std::fmt; use std::marker::PhantomData; use hex::{FromHex, FromHexError, ToHex}; use serde::{de, Deserializer, Serializer}; use serde::de::Visitor; /// A serializer that first encodes the argument as a hex-string pub fn serialize(value: &T, serializer: S) -> Result where S: Serializer, T: AsRef<[u8]>, { let mut output = String::new(); value.write_hex(&mut output).expect("Failed to write hex"); serializer.serialize_str(&output) } /// A deserializer that first encodes the argument as a hex-string pub fn deserialize<'de, D, T>(deserializer: D) -> Result where D: Deserializer<'de>, T: FromHex, { struct HexVisitor(PhantomData); impl<'de, T> Visitor<'de> for HexVisitor where T: FromHex, { type Value = T; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "hex ASCII text") } fn visit_str(self, v: &str) -> Result where E: de::Error, { T::from_hex(v).map_err(|e| match e { FromHexError::InvalidHexCharacter { c, index } => E::invalid_value( de::Unexpected::Char(c), &format!("Unexpected character {:?} as position {}", c, index).as_str(), ), FromHexError::InvalidStringLength => { E::invalid_length(v.len(), &"Unexpected length of hex string") } FromHexError::OddLength => E::invalid_length(v.len(), &"Odd length of hex string"), }) } } deserializer.deserialize_str(HexVisitor(PhantomData)) }