Something went wrong. Try again.
Typelevel cryptographic algo tracking crates.io/crates/evidence
typelevel cryptography util
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145//! Codec traits for encoding and decoding values.//!//! Codecs are marker types (e.g., [`Cbor`](cbor::Cbor), [`Json`](json::Json))//! that implement [`Encode`] and [`Decode`] for the value types they support.//!//! The marker types are always available regardless of feature flags.//! Enable the corresponding feature (`minicbor`, `serde_json`) to get//! [`Encode`]/[`Decode`] implementations backed by a concrete serialization//! library.
use alloc::vec::Vec;
pub mod cbor;pub mod json;
/// A codec that can encode values of type `T` to bytes.pub trait Encode<T: ?Sized> { /// The error type returned when encoding fails. type Error: core::fmt::Debug;
/// Encode `value` into a byte vector. /// /// # Errors /// /// Returns an error if the value cannot be serialized to bytes. fn encode(value: &T) -> Result<Vec<u8>, Self::Error>;}
/// A codec that can decode bytes into values of type `T`.pub trait Decode<T> { /// The error type returned when decoding fails. type Error;
/// Decode a value of type `T` from `bytes`. /// /// # Errors /// /// Returns an error if the bytes cannot be deserialized into `T`. fn decode(bytes: &[u8]) -> Result<T, Self::Error>;}
/// Marker trait for codecs that produce deterministic (canonical) encodings.////// A canonical codec guarantees that the same value always encodes to/// identical bytes, which is essential for content-addressed hashing.pub trait Canonical {}
/// Identity codec that passes bytes through unchanged.////// Useful for testing or when values are already serialized.////// # Example////// ```/// # #[cfg(feature = "sha2")]/// # {/// use evidence::digest::{Digest, sha2::Sha256};/// use evidence::codec::Identity;////// let data = b"hello world";/// let digest: Digest<[u8; 11], Sha256, Identity> = Digest::hash(data);/// assert_eq!(digest.as_bytes().len(), 32);/// # }/// ```#[derive(Debug, Clone, Copy)]pub enum Identity {}
impl<T: AsRef<[u8]>> Encode<T> for Identity { type Error = core::convert::Infallible;
fn encode(value: &T) -> Result<Vec<u8>, Self::Error> { Ok(value.as_ref().to_vec()) }}
/// Error returned when decoding with Identity codec fails due to length mismatch.#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub struct IdentityDecodeError { /// The number of bytes expected. pub expected: usize,
/// The number of bytes actually received. pub actual: usize,}
impl core::fmt::Display for IdentityDecodeError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "length mismatch: expected {} bytes, got {}", self.expected, self.actual ) }}
impl Decode<Vec<u8>> for Identity { type Error = core::convert::Infallible;
fn decode(bytes: &[u8]) -> Result<Vec<u8>, Self::Error> { Ok(bytes.to_vec()) }}
impl<const N: usize> Decode<[u8; N]> for Identity { type Error = IdentityDecodeError;
fn decode(bytes: &[u8]) -> Result<[u8; N], Self::Error> { bytes.try_into().map_err(|_| IdentityDecodeError { expected: N, actual: bytes.len(), }) }}
impl Canonical for Identity {}
/// A relaxed codec marker that tracks the underlying format without requiring encoding.////// Use this for deserialized values where you know the codec but don't have/// (or don't need) the encoder implementation.////// # Example////// ```/// # #[cfg(feature = "sha2")]/// # {/// use evidence::digest::{Digest, DigestUnchecked, sha2::Sha256};/// use evidence::codec::Relaxed;/// use hybrid_array::Array;////// // You received a digest over the network, encoded as CBOR/// enum Cbor {}////// let bytes: Array<u8, _> = Array::try_from([0u8; 32].as_slice()).unwrap();////// // Use Relaxed<Cbor> to track the format without needing Encode impl/// let digest: Digest<String, Sha256, Relaxed<Cbor>> = Digest::from_unchecked_array(bytes);////// // This would NOT compile — Relaxed<Cbor> doesn't implement Encode:/// // let d: Digest<String, Sha256, Relaxed<Cbor>> = Digest::hash(&my_string);/// # }/// ```#[derive(Debug)]pub struct Relaxed<C>(core::marker::PhantomData<C>);