1use crate::{EncodeValue, Encoder, Length, Result, Tagged};
4
5#[cfg(feature = "alloc")]
6use {crate::ErrorKind, alloc::vec::Vec, core::iter};
7
8pub trait Encodable {
10 fn encoded_len(&self) -> Result<Length>;
12
13 fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()>;
15
16 fn encode_to_slice<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> {
19 let mut encoder = Encoder::new(buf);
20 self.encode(&mut encoder)?;
21 encoder.finish()
22 }
23
24 #[cfg(feature = "alloc")]
27 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
28 fn encode_to_vec(&self, buf: &mut Vec<u8>) -> Result<Length> {
29 let expected_len = usize::try_from(self.encoded_len()?)?;
30 buf.reserve(expected_len);
31 buf.extend(iter::repeat(0).take(expected_len));
32
33 let mut encoder = Encoder::new(buf);
34 self.encode(&mut encoder)?;
35 let actual_len = encoder.finish()?.len();
36
37 if expected_len != actual_len {
38 return Err(ErrorKind::Incomplete {
39 expected_len: expected_len.try_into()?,
40 actual_len: actual_len.try_into()?,
41 }
42 .into());
43 }
44
45 actual_len.try_into()
46 }
47
48 #[cfg(feature = "alloc")]
50 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
51 fn to_vec(&self) -> Result<Vec<u8>> {
52 let mut buf = Vec::new();
53 self.encode_to_vec(&mut buf)?;
54 Ok(buf)
55 }
56}
57
58impl<T> Encodable for T
59where
60 T: EncodeValue + Tagged,
61{
62 fn encoded_len(&self) -> Result<Length> {
64 self.value_len().and_then(|len| len.for_tlv())
65 }
66
67 fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()> {
69 self.header()?.encode(encoder)?;
70 self.encode_value(encoder)
71 }
72}