serde-human-bytes 0.1.3

Optimized handling of `&[u8]` and `Vec<u8>` for Serde
Documentation
//! Pluggable encoding format for human-readable byte serialization.
//!
//! A [`Codec`] decides how `&[u8]` is rendered into / parsed from a string
//! when the underlying serde format is human-readable (JSON, YAML, TOML…).
//! For non-human-readable formats (bincode, postcard, CBOR…), the codec is
//! bypassed entirely and bytes are emitted verbatim.
//!
//! Three codecs ship with the crate:
//!
//! | Codec       | Encode               | Decode                     |
//! |-------------|----------------------|----------------------------|
//! | [`LowerHex`] | lowercase hex        | case-insensitive hex       |
//! | [`UpperHex`] | UPPERCASE hex        | case-insensitive hex       |
//! | [`Base64`]  | standard base64      | standard base64            |

use alloc::string::String;
use alloc::vec::Vec;
use serde::de::Error;

/// Encoding/decoding strategy used in human-readable mode.
pub trait Codec {
    /// Render bytes as the human-readable string form.
    fn encode(bytes: &[u8]) -> String;

    /// Parse the human-readable string form back into bytes.
    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E>;
}

/// Lowercase hex (default).
pub struct LowerHex;

impl Codec for LowerHex {
    fn encode(bytes: &[u8]) -> String {
        hex::encode(bytes)
    }
    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E> {
        hex::decode(s).map_err(E::custom)
    }
}

/// UPPERCASE hex. Decoder is case-insensitive, matching [`LowerHex`].
pub struct UpperHex;

impl Codec for UpperHex {
    fn encode(bytes: &[u8]) -> String {
        hex::encode_upper(bytes)
    }
    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E> {
        hex::decode(s).map_err(E::custom)
    }
}

/// Standard base64.
pub struct Base64;

impl Codec for Base64 {
    fn encode(bytes: &[u8]) -> String {
        ::base64::encode(bytes)
    }
    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E> {
        ::base64::decode(s).map_err(E::custom)
    }
}