1pub use {
8 cond::CodecIf,
9 endian::{CodecBe, CodecLe},
10 flags::CodecFlags,
11 join::CodecJoin,
12 len::{CodecLen, CodecLenValue},
13};
14
15use crate::{
16 iif, BitOr, Debug, Decodable, Deref, Encodable, EncodableLen, FmtResult, FmtWrite, Formatter,
17 IoError, IoErrorKind, IoRead, IoResult, IoTake, IoWrite, NonZero, PhantomData, TryFromIntError,
18};
19crate::_use! {basic::from_utf8}
20
21#[rustfmt::skip]
22mod endian {
23 use super::*;
24
25 #[doc = crate::doc_!(vendor: "encode")]
42 #[must_use]
43 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
44 pub struct CodecBe<W> {
45 num: W,
46 }
47 impl<W> CodecBe<W> {
48 pub const fn new(num: W) -> Self { Self { num } }
50 }
51
52 #[doc = crate::doc_!(vendor: "encode")]
69 #[must_use]
70 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
71 pub struct CodecLe<E> {
72 num: E,
73 }
74 impl<W> CodecLe<W> {
75 pub const fn new(num: W) -> Self { Self { num } }
77 }
78 macro_rules! impl_endian {
79 () => {
80 impl_endian![int: u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, isize];
81 impl_endian![prim: usize]; impl_endian![non0: usize];
82 impl_endian![float: f32, f64];
83 };
85 (int: $($T:ty),+) => {
86 impl_endian!(prim: $($T),+);
87 impl_endian!(non0: $($T),+);
88 $(
89 impl TryFrom<usize> for CodecBe<$T> {
90 type Error = TryFromIntError;
91 fn try_from(value: usize) -> Result<Self, Self::Error> {
92 <$T>::try_from(value).map(Self::new)
93 }
94 }
95 impl TryFrom<usize> for CodecLe<$T> {
96 type Error = TryFromIntError;
97 fn try_from(value: usize) -> Result<Self, Self::Error> {
98 <$T>::try_from(value).map(Self::new)
99 }
100 }
101 )+
102 };
103 (float: $($T:ty),+) => {
104 impl_endian!(prim: $($T),+);
105 };
106 (prim: $($T:ty),+) => {
107 $( impl From<$T> for CodecBe<$T> { fn from(num: $T) -> Self { Self { num } } }
109 impl From<CodecBe<$T>> for $T { fn from(be: CodecBe<$T>) -> Self { be.num } }
110 impl<W: IoWrite> Encodable<W> for CodecBe<$T> {
111 fn encode(&self, writer: &mut W) -> IoResult<usize> {
112 writer.write(&self.num.to_be_bytes()) } }
113 impl<R: IoRead> Decodable<R> for CodecBe<$T> {
114 type Output = $T;
115 fn decode(reader: &mut R) -> IoResult<$T> {
116 let mut buf = [0u8; size_of::<$T>()];
117 reader.read_exact(&mut buf)?;
118 Ok(<$T>::from_be_bytes(buf)) } }
119 impl From<$T> for CodecLe<$T> { fn from(num: $T) -> Self { Self { num } } }
121 impl From<CodecLe<$T>> for $T { fn from(be: CodecLe<$T>) -> Self { be.num } }
122 impl<W: IoWrite> Encodable<W> for CodecLe<$T> {
123 fn encode(&self, writer: &mut W) -> IoResult<usize> {
124 writer.write(&self.num.to_le_bytes()) } }
125 impl<R: IoRead> Decodable<R> for CodecLe<$T> {
126 type Output= $T;
127 fn decode(reader: &mut R) -> IoResult<$T> {
128 let mut buf = [0u8; size_of::<$T>()];
129 reader.read_exact(&mut buf)?;
130 Ok(<$T>::from_le_bytes(buf)) } }
131 )+
132 };
133 (non0: $($T:ty),+) => {
134 $( impl From<NonZero<$T>> for CodecBe<NonZero<$T>> {
136 fn from(num: NonZero<$T>) -> Self { Self { num } } }
137 impl From<CodecBe<NonZero<$T>>> for NonZero<$T> {
138 fn from(be: CodecBe<NonZero<$T>>) -> Self { be.num } }
139 impl<W: IoWrite> Encodable<W> for CodecBe<NonZero<$T>> {
140 fn encode(&self, writer: &mut W) -> IoResult<usize> {
141 writer.write(&self.num.get().to_be_bytes()) } }
142 impl<R: IoRead> Decodable<R> for CodecBe<NonZero<$T>> {
143 type Output = NonZero<$T>;
144 fn decode(reader: &mut R) -> IoResult<NonZero<$T>> {
145 let mut buf = [0u8; size_of::<$T>()];
146 reader.read_exact(&mut buf)?;
147 let num = <$T>::from_be_bytes(buf);
148 let non_zero = NonZero::<$T>::new(num)
149 .ok_or(IoError::new(IoErrorKind::InvalidData,
150 "Decoded zero for NonZero type"))?;
151 Ok(non_zero) } }
152 impl From<NonZero<$T>> for CodecLe<NonZero<$T>> {
154 fn from(num: NonZero<$T>) -> Self { Self { num } } }
155 impl From<CodecLe<NonZero<$T>>> for NonZero<$T> {
156 fn from(be: CodecLe<NonZero<$T>>) -> Self { be.num } }
157 impl<W: IoWrite> Encodable<W> for CodecLe<NonZero<$T>> {
158 fn encode(&self, writer: &mut W) -> IoResult<usize> {
159 writer.write(&self.num.get().to_be_bytes()) } }
160 impl<R: IoRead> Decodable<R> for CodecLe<NonZero<$T>> {
161 type Output = NonZero<$T>;
162 fn decode(reader: &mut R) -> IoResult<NonZero<$T>> {
163 let mut buf = [0u8; size_of::<$T>()];
164 reader.read_exact(&mut buf)?;
165 let num = <$T>::from_le_bytes(buf);
166 let non_zero = NonZero::<$T>::new(num)
167 .ok_or(IoError::new(IoErrorKind::InvalidData,
168 "Decoded zero for NonZero type"))?;
169 Ok(non_zero) } }
170 )+
171 }
172 }
173 impl_endian![];
174}
175#[rustfmt::skip]
176mod cond {
177 use super::*;
178
179 #[doc = crate::doc_!(vendor: "encode")]
195 #[must_use]
196 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
197 pub struct CodecIf<E, F> { encodable: E, condition: F }
198 impl<E, F: Fn(&E) -> bool> CodecIf<E, F> {
199 pub const fn new(encodable: E, condition: F) -> Self { Self { encodable, condition } }
201 }
202 impl<E, F> AsRef<E> for CodecIf<E, F> { fn as_ref(&self) -> &E { &self.encodable } }
203 impl<E, F> Deref for CodecIf<E, F> {
204 type Target = E;
205 fn deref(&self) -> &Self::Target { self.as_ref() }
206 }
207 impl<E: Encodable<W>, W: IoWrite, F: Fn(&E) -> bool> Encodable<W> for CodecIf<E, F> {
208 fn encode(&self, writer: &mut W) -> IoResult<usize> {
209 if (self.condition)(&self.encodable) {
210 self.encodable.encode(writer)
211 } else {
212 Ok(0)
213 }
214 }
215 }
216}
217#[rustfmt::skip]
218mod flags {
219 use super::*;
220
221 #[doc = crate::doc_!(vendor: "encode")]
240 #[must_use]
241 #[repr(transparent)]
242 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
243 pub struct CodecFlags([bool; 8]);
244 impl CodecFlags {
245 pub const fn new(flags: [bool; 8]) -> Self { Self(flags) }
247 pub fn from_slice(slice: &[bool]) -> Self {
251 let mut flags = [false; 8];
252 for (i, &b) in slice.iter().take(8).enumerate() { flags[i] = b; }
253 Self(flags)
254 }
255 pub fn from_iter<T, I, F>(iter: I, mut f: F) -> Self
259 where
260 I: IntoIterator<Item = T>,
261 F: FnMut(T) -> bool,
262 {
263 let mut flags = [false; 8];
264 for (i, v) in iter.into_iter().take(8).enumerate() {
265 flags[i] = f(v);
266 }
267 Self(flags)
268 }
269 }
270 impl Debug for CodecFlags {
271 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
272 write!(f, "CodecFlags({:08b})", u8::from(*self)) }
273 }
274 impl Deref for CodecFlags {
275 type Target = [bool; 8];
276 fn deref(&self) -> &Self::Target { &self.0 }
277 }
278 impl AsRef<[bool; 8]> for CodecFlags {
279 fn as_ref(&self) -> &[bool; 8] { &self.0 }
280 }
281 impl From<u8> for CodecFlags {
282 fn from(from: u8) -> Self {
283 let mut slice = [false; 8];
284 slice.iter_mut().enumerate().rev().for_each(|(i, v)| { *v = (from & (1 << i)) != 0; });
285 Self(slice) }
286 }
287 impl From<CodecFlags> for u8 {
288 fn from(from: CodecFlags) -> Self {
289 from.0.into_iter().rev().enumerate()
290 .filter_map(|(i, v)| v.then_some(1 << i)).fold(0u8, BitOr::bitor) }
291 }
292 impl<W: IoWrite> Encodable<W> for CodecFlags {
293 fn encode(&self, encoder: &mut W) -> IoResult<usize> {
294 u8::from(*self).encode(encoder) }
295 }
296}
297#[rustfmt::skip]
298mod join {
299 use super::*;
300
301 #[doc = crate::doc_!(vendor: "encode")]
325 #[must_use]
326 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
327 pub struct CodecJoin<E, S> {
328 encodable_iter: E,
329 separator: Option<S>,
330 }
331 impl<E> CodecJoin<E, ()> {
332 pub const fn new(encodable_iter: E) -> Self {
334 Self { encodable_iter, separator: None::<()> }
335 }
336 }
337 impl<E, S> CodecJoin<E, S> {
338 pub const fn with(encodable_iter: E, separator: S) -> Self {
340 Self { encodable_iter, separator: Some(separator) }
341 }
342 }
343 impl<E, S, W: IoWrite> Encodable<W> for CodecJoin<E, S>
344 where
345 E: Clone + IntoIterator,
346 E::Item: Encodable<W>,
347 S: Encodable<W>,
348 {
349 fn encode(&self, writer: &mut W) -> IoResult<usize> {
350 let mut total = 0;
351 if let Some(sep) = &self.separator {
352 let mut is_first = true;
353 for encodable in self.encodable_iter.clone() {
354 iif![is_first; is_first = false; total += sep.encode(writer)?];
355 total += encodable.encode(writer)?;
356 }
357 } else {
358 for encodable in self.encodable_iter.clone() {
359 total += encodable.encode(writer)?;
360 }
361 }
362 Ok(total)
363 }
364 }
365}
366#[rustfmt::skip]
367mod len {
368 use super::*;
369
370 #[doc = crate::doc_!(vendor: "encode")]
386 #[must_use]
387 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
388 pub struct CodecLen { size: usize, }
389 impl CodecLen {
390 pub const fn new() -> Self { Self { size: 0 } }
392 pub const fn size(&self) -> usize { self.size }
394 }
395 impl From<CodecLen> for usize {
396 fn from(encoder: CodecLen) -> usize { encoder.size }
397 }
398 impl FmtWrite for CodecLen {
399 fn write_str(&mut self, s: &str) -> FmtResult<()> { self.size += s.len(); Ok(()) }
400 }
401 impl IoWrite for CodecLen {
402 fn write(&mut self, slice: &[u8]) -> IoResult<usize> { self.size += slice.len(); Ok(self.size) }
403 fn flush(&mut self) -> IoResult<()> { Ok(()) }
404 }
405
406 #[doc = crate::doc_!(vendor: "encode")]
457 #[must_use]
458 #[doc(alias("length", "prefix", "TLV"))]
459 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
460 #[repr(transparent)]
461 pub struct CodecLenValue<E, CodecEndian> {
462 encodable: E,
463 phantom: PhantomData<CodecEndian>,
464 }
465 impl<E, CodecEndian> CodecLenValue<E, CodecEndian> {
466 pub const fn new(encodable: E) -> Self { Self { encodable, phantom: PhantomData, } }
468 }
469 impl<E, CodecEndian, W: IoWrite> Encodable<W> for CodecLenValue<E, CodecEndian>
470 where
471 E: Encodable<W> + EncodableLen,
472 CodecEndian: From<<CodecEndian as CodecEndianLen>::Len> + Encodable<W> + CodecEndianLen,
473 <CodecEndian as CodecEndianLen>::Len: TryFrom<usize>,
474 {
475 fn encode(&self, writer: &mut W) -> IoResult<usize> {
476 let len = self.encodable.encoded_size()?;
477 let len = <<CodecEndian as CodecEndianLen>::Len as TryFrom<usize>>::try_from(len)
478 .map_err(|_| IoError::new(IoErrorKind::InvalidInput, "Length conversion failed"))?;
479 let mut total = CodecEndian::from(len).encode(writer)?;
480 total += self.encodable.encode(writer)?;
481 Ok(total)
482 }
483 }
484 impl<D, O, CodecEndian, R> Decodable<R> for CodecLenValue<D, CodecEndian>
485 where
486 for<'i> D: Decodable<IoTake<&'i mut R>, Output = O>,
488 CodecEndian: Decodable<R, Output = <CodecEndian as CodecEndianLen>::Len> + CodecEndianLen,
490 R: IoRead,
491 for<'r> &'r mut R: IoRead,
492 {
493 type Output = O;
494 fn decode(reader: &mut R) -> IoResult<Self::Output> {
495 let len_encoded = CodecEndian::decode(reader)?;
496 let len: usize = len_encoded.try_into().map_err(|_| {
497 IoError::new(IoErrorKind::InvalidData, "Invalid length value")
498 })?;
499 let mut limited_reader = reader.take(len as u64);
500 D::decode(&mut limited_reader)
501 }
502 }
503
504 impl<'a, CodecEndian> Decodable<&'a mut &'a [u8]> for CodecLenValue<&'a str, CodecEndian>
506 where
507 CodecEndian: CodecEndianLen + Decodable<&'a mut &'a [u8],
508 Output = <CodecEndian as CodecEndianLen>::Len>,
509 <CodecEndian as CodecEndianLen>::Len: TryInto<usize>,
510 {
511 type Output = &'a str;
512 fn decode(reader: &mut &'a mut &'a [u8]) -> IoResult<Self::Output> {
513 fn decode_str<'a>(buf: &mut &'a [u8], len: usize) -> IoResult<&'a str> {
514 if buf.len() < len {
515 return Err(IoError::new(IoErrorKind::UnexpectedEof, "Not enough bytes"));
516 }
517 let (s_bytes, rest) = buf.split_at(len);
518 *buf = rest;
519 from_utf8(s_bytes)
520 .map_err(|_| IoError::new(IoErrorKind::InvalidData, "Invalid UTF-8"))
521 }
522 let len_encoded = CodecEndian::decode(reader)?;
523 let len: usize = len_encoded.try_into().map_err(|_| {
524 IoError::new(IoErrorKind::InvalidData, "Invalid length value")
525 })?;
526 decode_str(reader, len)
527 }
528 }
529
530 trait CodecEndianLen { type Len: TryInto<usize> + TryFrom<usize>; }
541 macro_rules! impl_codec_endian_len { ($($T:ty),+) => { $(
542 impl CodecEndianLen for CodecLe<$T> { type Len = $T; }
543 impl CodecEndianLen for CodecBe<$T> { type Len = $T; }
544 )+ }; }
545 impl_codec_endian_len![u8, u16, u32, usize];
546 impl CodecEndianLen for u8 { type Len = u8; }
547}