devela/data/codec/encode/
traits.rs

1// devela::data::codec::encode::traits
2//
3//! Define `Encodable`, `EncodableLen`.
4//
5// IMPROVE: do not return IoError, but custom simpler error.
6// > https://www.reddit.com/r/rust/comments/1iv3rb3/rust_rant_contest_stdioerror_the_oversized_junk/
7// - InvalidData:
8//   - decoded 0 for nonzerotype
9//   - invalid length value
10//   - invalid utf8
11//   - invalid utf8 sequence
12//   - invalid c string
13//   - invalid utf-32 char
14//   - invalid boolean value
15// - InvalidInput
16//   - length conversion failed
17// - UnexpectedEof
18//   - not enough bytes
19//   - empty utf-8 sequence
20// - other
21//   - formatting failed
22
23use crate::{CodecLen, IoRead, IoResult, IoWrite};
24
25/// A type that can be decoded from an I/O reader.
26///
27/// See also [`Encodable`].
28pub trait Decodable<R: IoRead>: Sized {
29    /// The type produced when decoding.
30    type Output;
31
32    /// Decodes `Self` from the given `reader`, returning the decoded value.
33    ///
34    /// # Errors
35    /// Returns an [`IoError`][crate::IoError] if decoding fails.
36    fn decode(reader: &mut R) -> IoResult<Self::Output>;
37}
38
39/// A type that can be encoded into an I/O writer.
40///
41/// See also [`Decodable`].
42#[doc = crate::doc_!(vendor: "encode")]
43pub trait Encodable<W: IoWrite> {
44    /// Encodes `self` into the given `writer`, returning the bytes written.
45    ///
46    /// # Errors
47    /// Returns [`IoError`][crate::IoError] if encoding fails.
48    fn encode(&self, writer: &mut W) -> IoResult<usize>;
49}
50
51/// A type that can compute the size of its encoded form without actual encoding.
52///
53/// This trait is automatically implemented for all types that implement
54/// [`Encodable`] with [`CodecLen`].
55///
56/// See [`CodecLen`] for details on length-based encoding.
57#[doc = crate::doc_!(vendor: "encode")]
58pub trait EncodableLen: Encodable<CodecLen> {
59    /// Computes the size of `self` when encoded.
60    ///
61    /// This method simulates encoding without writing any data,
62    /// allowing for preallocation or buffer sizing.
63    fn encoded_size(&self) -> IoResult<usize> {
64        let mut encoder = CodecLen::new();
65        self.encode(&mut encoder)?;
66        Ok(encoder.size())
67    }
68}
69impl<T: Encodable<CodecLen>> EncodableLen for T {}