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§
Required Methods§
Sourcefn create_bytes(value: &T) -> [u8; N]
fn create_bytes(value: &T) -> [u8; N]
Converts the value into bytes. This is used for serialization.
Provided Methods§
Sourcefn serialize<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
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.
Sourcefn deserialize<'de, D>(deserializer: D) -> Result<T, D::Error>where
D: Deserializer<'de>,
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.