hex_buffer_serde

Trait ConstHex

Source
pub trait ConstHex<T, const N: usize> {
    type Error: Display;

    // Required methods
    fn create_bytes(value: &T) -> [u8; N];
    fn from_bytes(bytes: [u8; N]) -> Result<T, Self::Error>;

    // Provided methods
    fn serialize<S: Serializer>(
        value: &T,
        serializer: S,
    ) -> Result<S::Ok, S::Error> { ... }
    fn deserialize<'de, D>(deserializer: D) -> Result<T, D::Error>
       where D: Deserializer<'de> { ... }
}
Expand description

Analogue of Hex for values that have constant-length byte presentation. This allows to avoid dependency on the alloc crate and expresses the byte length constraint via types.

§Examples

use hex_buffer_serde::{ConstHex, ConstHexForm};

#[derive(Serialize, Deserialize)]
struct Simple {
    #[serde(with = "ConstHexForm")]
    array: [u8; 16],
    // `array` will be serialized as 32-char hex string
}

Similarly to Hex, it is possible to define proxies implementing ConstHex for external types, for example, keys from ed25519-dalek:

use ed25519::{PublicKey, SecretKey};
use hex_buffer_serde::ConstHex;

struct KeyHex(());

impl ConstHex<PublicKey, 32> for KeyHex {
    type Error = ed25519::SignatureError;

    fn create_bytes(pk: &PublicKey) -> [u8; 32] {
        pk.to_bytes()
    }

    fn from_bytes(bytes: [u8; 32]) -> Result<PublicKey, Self::Error> {
        PublicKey::from_bytes(&bytes)
        // although `bytes` always has correct length, not all
        // 32-byte sequences are valid Ed25519 public keys.
    }
}

impl ConstHex<SecretKey, 32> for KeyHex {
    type Error = core::convert::Infallible;

    fn create_bytes(sk: &SecretKey) -> [u8; 32] {
        sk.to_bytes()
    }

    fn from_bytes(bytes: [u8; 32]) -> Result<SecretKey, Self::Error> {
        Ok(SecretKey::from_bytes(&bytes).unwrap())
        // ^ unwrap() is safe; any 32-byte sequence is a valid
        // Ed25519 secret key.
    }
}

#[derive(Serialize, Deserialize)]
struct KeyPair {
    #[serde(with = "KeyHex")]
    public: PublicKey,
    #[serde(with = "KeyHex")]
    secret: SecretKey,
}

Required Associated Types§

Source

type Error: Display

Error returned on unsuccessful deserialization.

Required Methods§

Source

fn create_bytes(value: &T) -> [u8; N]

Converts the value into bytes. This is used for serialization.

Source

fn from_bytes(bytes: [u8; N]) -> Result<T, Self::Error>

Creates a value from the byte slice.

§Errors

If this method fails, it should return a human-readable error description conforming to serde conventions (no upper-casing of the first letter, no punctuation at the end).

Provided Methods§

Source

fn serialize<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error>

Serializes the value for serde. This method is not meant to be overridden.

The serialization is a lower-case hex string for human-readable serializers (e.g., JSON or TOML), and the original bytes returned by Self::create_bytes() for non-human-readable ones.

Source

fn deserialize<'de, D>(deserializer: D) -> Result<T, D::Error>
where D: Deserializer<'de>,

Deserializes a value using serde. This method is not meant to be overridden.

If the deserializer is human-readable (e.g., JSON or TOML), this method expects a hex-encoded string. Otherwise, the method expects a byte array.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§