1use crate::{checked::CheckedSum, writer::Writer, Error};
7use core::str;
8
9#[cfg(feature = "alloc")]
10use alloc::{string::String, vec::Vec};
11
12#[cfg(feature = "bytes")]
13use bytes::Bytes;
14
15#[cfg(feature = "pem")]
16use {
17 crate::PEM_LINE_WIDTH,
18 pem::{LineEnding, PemLabel},
19};
20
21pub trait Encode {
25 fn encoded_len(&self) -> Result<usize, Error>;
27
28 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error>;
30
31 fn encoded_len_prefixed(&self) -> Result<usize, Error> {
34 [4, self.encoded_len()?].checked_sum()
35 }
36
37 fn encode_prefixed(&self, writer: &mut impl Writer) -> Result<(), Error> {
40 self.encoded_len()?.encode(writer)?;
41 self.encode(writer)
42 }
43}
44
45#[cfg(feature = "pem")]
50pub trait EncodePem: Encode + PemLabel {
51 fn encode_pem<'o>(&self, line_ending: LineEnding, out: &'o mut [u8]) -> Result<&'o str, Error>;
54
55 #[cfg(feature = "alloc")]
58 fn encode_pem_string(&self, line_ending: LineEnding) -> Result<String, Error>;
59}
60
61#[cfg(feature = "pem")]
62impl<T: Encode + PemLabel> EncodePem for T {
63 fn encode_pem<'o>(&self, line_ending: LineEnding, out: &'o mut [u8]) -> Result<&'o str, Error> {
64 let mut writer =
65 pem::Encoder::new_wrapped(Self::PEM_LABEL, PEM_LINE_WIDTH, line_ending, out)
66 .map_err(Error::from)?;
67
68 self.encode(&mut writer)?;
69 let encoded_len = writer.finish().map_err(Error::from)?;
70 str::from_utf8(&out[..encoded_len]).map_err(Error::from)
71 }
72
73 #[cfg(feature = "alloc")]
74 fn encode_pem_string(&self, line_ending: LineEnding) -> Result<String, Error> {
75 let encoded_len = pem::encapsulated_len_wrapped(
76 Self::PEM_LABEL,
77 PEM_LINE_WIDTH,
78 line_ending,
79 self.encoded_len()?,
80 )
81 .map_err(Error::from)?;
82
83 let mut buf = vec![0u8; encoded_len];
84 let actual_len = self.encode_pem(line_ending, &mut buf)?.len();
85 buf.truncate(actual_len);
86 String::from_utf8(buf).map_err(Error::from)
87 }
88}
89
90impl Encode for u8 {
92 fn encoded_len(&self) -> Result<usize, Error> {
93 Ok(1)
94 }
95
96 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
97 writer.write(&[*self])
98 }
99}
100
101impl Encode for u32 {
109 fn encoded_len(&self) -> Result<usize, Error> {
110 Ok(4)
111 }
112
113 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
114 writer.write(&self.to_be_bytes())
115 }
116}
117
118impl Encode for u64 {
125 fn encoded_len(&self) -> Result<usize, Error> {
126 Ok(8)
127 }
128
129 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
130 writer.write(&self.to_be_bytes())
131 }
132}
133
134impl Encode for usize {
141 fn encoded_len(&self) -> Result<usize, Error> {
142 Ok(4)
143 }
144
145 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
146 u32::try_from(*self)?.encode(writer)
147 }
148}
149
150impl Encode for [u8] {
158 fn encoded_len(&self) -> Result<usize, Error> {
159 [4, self.len()].checked_sum()
160 }
161
162 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
163 self.len().encode(writer)?;
164 writer.write(self)
165 }
166}
167
168impl<const N: usize> Encode for [u8; N] {
176 fn encoded_len(&self) -> Result<usize, Error> {
177 self.as_slice().encoded_len()
178 }
179
180 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
181 self.as_slice().encode(writer)
182 }
183}
184
185impl Encode for &str {
203 fn encoded_len(&self) -> Result<usize, Error> {
204 self.as_bytes().encoded_len()
205 }
206
207 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
208 self.as_bytes().encode(writer)
209 }
210}
211
212#[cfg(feature = "alloc")]
213impl Encode for Vec<u8> {
214 fn encoded_len(&self) -> Result<usize, Error> {
215 self.as_slice().encoded_len()
216 }
217
218 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
219 self.as_slice().encode(writer)
220 }
221}
222
223#[cfg(feature = "alloc")]
224impl Encode for String {
225 fn encoded_len(&self) -> Result<usize, Error> {
226 self.as_str().encoded_len()
227 }
228
229 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
230 self.as_str().encode(writer)
231 }
232}
233
234#[cfg(feature = "alloc")]
235impl Encode for Vec<String> {
236 fn encoded_len(&self) -> Result<usize, Error> {
237 self.iter().try_fold(4usize, |acc, string| {
238 acc.checked_add(string.encoded_len()?).ok_or(Error::Length)
239 })
240 }
241
242 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
243 self.encoded_len()?
244 .checked_sub(4)
245 .ok_or(Error::Length)?
246 .encode(writer)?;
247
248 for entry in self {
249 entry.encode(writer)?;
250 }
251
252 Ok(())
253 }
254}
255
256#[cfg(feature = "bytes")]
257impl Encode for Bytes {
258 fn encoded_len(&self) -> Result<usize, Error> {
259 self.as_ref().encoded_len()
260 }
261
262 fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> {
263 self.as_ref().encode(writer)
264 }
265}