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}