Skip to main content

serde_human_bytes/
codec.rs

1//! Pluggable encoding format for human-readable byte serialization.
2//!
3//! A [`Codec`] decides how `&[u8]` is rendered into / parsed from a string
4//! when the underlying serde format is human-readable (JSON, YAML, TOML…).
5//! For non-human-readable formats (bincode, postcard, CBOR…), the codec is
6//! bypassed entirely and bytes are emitted verbatim.
7//!
8//! Three codecs ship with the crate:
9//!
10//! | Codec       | Encode               | Decode                     |
11//! |-------------|----------------------|----------------------------|
12//! | [`LowerHex`] | lowercase hex        | case-insensitive hex       |
13//! | [`UpperHex`] | UPPERCASE hex        | case-insensitive hex       |
14//! | [`Base64`]  | standard base64      | standard base64            |
15
16use alloc::string::String;
17use alloc::vec::Vec;
18use serde::de::Error;
19
20/// Encoding/decoding strategy used in human-readable mode.
21pub trait Codec {
22    /// Render bytes as the human-readable string form.
23    fn encode(bytes: &[u8]) -> String;
24
25    /// Parse the human-readable string form back into bytes.
26    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E>;
27}
28
29/// Lowercase hex (default).
30pub struct LowerHex;
31
32impl Codec for LowerHex {
33    fn encode(bytes: &[u8]) -> String {
34        hex::encode(bytes)
35    }
36    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E> {
37        hex::decode(s).map_err(E::custom)
38    }
39}
40
41/// UPPERCASE hex. Decoder is case-insensitive, matching [`LowerHex`].
42pub struct UpperHex;
43
44impl Codec for UpperHex {
45    fn encode(bytes: &[u8]) -> String {
46        hex::encode_upper(bytes)
47    }
48    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E> {
49        hex::decode(s).map_err(E::custom)
50    }
51}
52
53/// Standard base64.
54pub struct Base64;
55
56impl Codec for Base64 {
57    fn encode(bytes: &[u8]) -> String {
58        ::base64::encode(bytes)
59    }
60    fn decode<E: Error>(s: &str) -> Result<Vec<u8>, E> {
61        ::base64::decode(s).map_err(E::custom)
62    }
63}