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 {}