ufotofu_codec/
decode.rs

1#[cfg(feature = "alloc")]
2extern crate alloc;
3#[cfg(feature = "std")]
4extern crate std;
5
6use core::convert::Infallible;
7use core::future::Future;
8
9use ufotofu::{producer::FromSlice, BulkProducer};
10
11use crate::DecodeError;
12
13/// Methods for decoding a value that belongs to an *encoding relation*.
14///
15/// API contracts:
16///
17/// - The result of decoding must depend only on the decoded bytes, not on details of the producer such as when it yields or how many items it exposes at a time.
18/// - `decode` must not read any bytes beyond the end of the encoding.
19/// - For types that also implement [`Encodable`](crate::Encodable) and [`Eq`], encoding a value and then decoding it must yield a value equal to the original.
20pub trait Decodable: Sized {
21    /// Reason why decoding can fail (beyond an unexpected end of input or a producer error).
22    type ErrorReason;
23
24    /// Decodes the bytes produced by the given producer into a `Self`, or yields an error if the producer does not produce a valid encoding.
25    fn decode<P>(
26        producer: &mut P,
27    ) -> impl Future<Output = Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>>
28    where
29        P: BulkProducer<Item = u8>,
30        Self: Sized;
31
32    /// Decodes from a slice instead of a producer.
33    fn decode_from_slice(
34        enc: &[u8],
35    ) -> impl Future<Output = Result<Self, DecodeError<(), Infallible, Self::ErrorReason>>> {
36        async { Self::decode(&mut FromSlice::new(enc)).await }
37    }
38}
39
40/// Decoding for an *encoding relation* with a one-to-one mapping between values and their codes (i.e., the relation is a [bijection](https://en.wikipedia.org/wiki/Bijection)).
41///
42/// This may specialise an arbitrary encoding relation to implement a canonic subset.
43///
44/// API contracts:
45///
46/// - Two nonequal codes must not decode to the same value with `decode_canonic`.
47/// - Any code that decodes via `decode_canonic` must also decode via `decode` to the same value.
48/// - For types that also implement [`Encodable`](crate::Encodable) and [`Eq`], if canonically decoding a bytestring suceedes, then reencoding the resulting value must result in the original bytestring.
49///
50/// There is no corresponding `EncodableCanonic` trait, because `Encodable` already fulfils the dual requirement of two nonequal values yielding nonequal codes.
51pub trait DecodableCanonic: Decodable {
52    /// The type for reporting that the bytestring to decode was not a valid canonic encoding of any value of type `Self`.
53    ///
54    /// Typically contains at least as much information as [`Self::ErrorReason`](Decodable::ErrorReason). If the encoding relation implemented by [`Decodable`] is already canonic, then [`ErrorCanonic`](DecodableCanonic::ErrorCanonic) should be equal to [`Self::ErrorReason`](Decodable::ErrorReason).
55    type ErrorCanonic: From<Self::ErrorReason>;
56
57    /// Decodes the bytes produced by the given producer into a `Self`, and errors if the input encoding is not the canonical one.
58    fn decode_canonic<P>(
59        producer: &mut P,
60    ) -> impl Future<Output = Result<Self, DecodeError<P::Final, P::Error, Self::ErrorCanonic>>>
61    where
62        P: BulkProducer<Item = u8>,
63        Self: Sized;
64
65    /// Decodes from a slice instead of a producer, and errors if the input encoding is not the canonical one.
66    fn decode_canonic_from_slice(
67        enc: &[u8],
68    ) -> impl Future<Output = Result<Self, DecodeError<(), Infallible, Self::ErrorCanonic>>> {
69        async { Self::decode_canonic(&mut FromSlice::new(enc)).await }
70    }
71}
72
73/// A decodable that introduces no asynchrony beyond that of `.await`ing the producer. This is essentially a marker trait by which to tell other programmers about this property. As a practical benefit, the default methods of this trait allow for convenient synchronous decoding by internally using producers that are known to never block.
74pub trait DecodableSync: Decodable {
75    /// Synchronously decodes from a slice instead of a producer.
76    fn sync_decode_from_slice(
77        enc: &[u8],
78    ) -> Result<Self, DecodeError<(), Infallible, Self::ErrorReason>> {
79        pollster::block_on(Self::decode_from_slice(enc))
80    }
81
82    /// Synchronously and absolutely decodes from a slice instead of a producer, and errors if the input encoding is not the canonical one.
83    fn sync_decode_canonic_from_slice(
84        enc: &[u8],
85    ) -> Result<Self, DecodeError<(), Infallible, Self::ErrorCanonic>>
86    where
87        Self: DecodableCanonic,
88    {
89        pollster::block_on(Self::decode_canonic_from_slice(enc))
90    }
91}