Skip to main content

mldsa_native_rs/wrapper/utils/
transcoding.rs

1//! Utilities for transcoding between types and byte slices.
2//!
3//! This module provides traits and error types for converting types to and from byte slices,
4//! enabling generic and fallible parsing and serialization.
5//!
6//! # Traits
7//!
8//! - [`AsBytes`]: For types that can be represented as a byte slice. Blanket implementation for all types implementing `AsRef<[u8]>`.
9//! - [`FromBytes`]: For types that can be fallibly parsed from a byte slice. Blanket implementation for types implementing `TryFrom<&[u8]>`.
10//!
11//! # Error Types
12//!
13//! - [`TranscodingError`]: Generic error type for transcoding operations.
14//!
15//! # Examples
16//!
17//! ```rust
18//! use mldsa_native_rs::transcoding::{AsBytes, FromBytes};
19//!
20//! let bytes: &[u8] = &[1, 2, 3];
21//! let vec = Vec::<u8>::from_bytes(bytes).unwrap();
22//! assert_eq!(vec.as_bytes(), bytes);
23//! ```
24
25use core::convert::TryFrom;
26
27/// Error type for transcoding operations.
28#[derive(Debug)]
29pub struct TranscodingError;
30
31impl core::error::Error for TranscodingError {}
32
33impl core::fmt::Display for TranscodingError {
34    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35        write!(f, "Transcoding error")
36    }
37}
38
39impl From<crate::FFIError> for TranscodingError {
40    fn from(_: crate::FFIError) -> Self {
41        TranscodingError {}
42    }
43}
44
45impl From<generic_array::LengthError> for TranscodingError {
46    fn from(_: generic_array::LengthError) -> Self {
47        TranscodingError {}
48    }
49}
50
51/// Trait for types that can be represented as a byte slice.
52pub trait AsBytes: AsRef<[u8]> {
53    /// Returns a reference to the underlying byte slice.
54    #[inline]
55    fn as_bytes(&self) -> &[u8] {
56        self.as_ref()
57    }
58}
59
60// Anything that is `AsRef<[u8]>` gets `ToBytes` for free.
61impl<T> AsBytes for T where T: AsRef<[u8]> {}
62
63/// Fallible parse from a byte slice.
64pub trait FromBytes: Sized {
65    /// The error type returned when parsing from bytes fails.
66    type Error;
67
68    /// Try to build an instance of this object from a byte slice.
69    ///
70    /// # Errors
71    ///
72    /// This function will return [`Self::Error`] on failure.
73    fn from_bytes(input: &[u8]) -> Result<Self, Self::Error>;
74}
75
76// Blanket impl: any `T` that can `TryFrom<&[u8]>` with a *single* error type `E`
77// (independent of the slice lifetime) implements `FromBytes`.
78impl<T, E> FromBytes for T
79where
80    for<'a> T: TryFrom<&'a [u8], Error = E>,
81{
82    type Error = E;
83
84    #[inline]
85    fn from_bytes(input: &[u8]) -> Result<Self, Self::Error> {
86        <T as TryFrom<&[u8]>>::try_from(input)
87    }
88}