compact_encoding/
lib.rs

1#![forbid(unsafe_code, missing_docs)]
2#![cfg_attr(test, deny(warnings))]
3//! # Series of compact encoding schemes for building small and fast parsers and serializers
4//!
5//! Binary compatible with the
6//! [original JavaScript compact-encoding library](https://github.com/compact-encoding/compact-encoding/).
7//!
8//! ## Usage
9//!
10//! The simplest way to encoded and decode a some data is using the [`to_encoded_bytes`] and
11//! [`map_decode`] macros:
12//! ```
13//! use compact_encoding::{map_decode, to_encoded_bytes};
14//!
15//! let number = 41_u32;
16//! let word = "hi";
17//!
18//! let encoded_buffer = to_encoded_bytes!(number, word);
19//! let ((number_dec, word_dec), remaining_buffer) = map_decode!(&encoded_buffer, [u32, String]);
20//!
21//! assert!(remaining_buffer.is_empty());
22//! assert_eq!(number_dec, number);
23//! assert_eq!(word_dec, word);
24//! # Ok::<(), Box<dyn std::error::Error>>(())
25//! ```
26//! ### Manual encoding and decoding
27//!
28//! When more fine-grained control of encoding and decoding is needed you manually do each step of
29//! encoding and decoding like in the following example, where we want to use a fixed width
30//! encoding for `number` (instead of the default variable width encoding). It shows how to
31//! manually calculate the needed buffer size, create the buffer, encode data, and decode it.
32//! ```
33//! use compact_encoding::{CompactEncoding, FixedWidthEncoding, FixedWidthU32};
34//!
35//! let number = 41_u32;
36//! let word = "hi";
37//!
38//! // Use `encoded_size` to figure out how big a buffer should be
39//! let size = number.as_fixed_width().encoded_size()? + word.encoded_size()?;
40//!
41//! // Create a buffer with the calculated size
42//! let mut buffer = vec![0; size];
43//! assert_eq!(buffer.len(), 4 + 1 + 2);
44//!
45//! // Then actually encode the values
46//! let mut remaining_buffer = number.as_fixed_width().encode(&mut buffer)?;
47//! remaining_buffer = word.encode(remaining_buffer)?;
48//! assert!(remaining_buffer.is_empty());
49//! assert_eq!(buffer.to_vec(), vec![41_u8, 0, 0, 0, 2_u8, b'h', b'i']);
50//!
51//! // `buffer` now contains all the encoded data, and we can decode from it
52//! let (number_dec, remaining_buffer) = FixedWidthU32::decode(&buffer)?;
53//! let (word_dec, remaining_buffer) = String::decode(remaining_buffer)?;
54//! assert!(remaining_buffer.is_empty());
55//! assert_eq!(number_dec, number);
56//! assert_eq!(word_dec, word);
57//! # Ok::<(), Box<dyn std::error::Error>>(())
58//! ```
59//!
60//! ### Implementing CompactEncoding for custom types
61//!
62//! Here we demonstrate how to implement [`CompactEncoding`] for a custom struct.
63//! ```
64//! use compact_encoding::{
65//!     map_decode, map_encode, sum_encoded_size, to_encoded_bytes, CompactEncoding, EncodingError,
66//! };
67//!
68//! #[derive(Debug, PartialEq)]
69//! struct MyStruct {
70//!     some_flag: bool,
71//!     values: Option<Vec<[u8; 32]>>,
72//!     other: String,
73//!     stuff: u64,
74//! }
75//!
76//! impl CompactEncoding for MyStruct {
77//!     fn encoded_size(&self) -> Result<usize, EncodingError> {
78//!         Ok(1 /* flags */ + {
79//!              /* handle option values */
80//!             if let Some(values) = &self.values  {
81//!                 values.encoded_size()?
82//!             } else {
83//!                 0
84//!             }
85//!         } + sum_encoded_size!(&self.other, &self.stuff))
86//!     }
87//!
88//!     fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
89//!         let mut flags: u8 = 0;
90//!         if self.some_flag {
91//!             flags |= 1;
92//!         }
93//!         if self.values.is_some() {
94//!             flags |= 2;
95//!         }
96//!         let mut rest = flags.encode(buffer)?;
97//!         if let Some(values) = &self.values {
98//!             rest = values.encode(rest)?;
99//!         }
100//!         Ok(map_encode!(rest, self.other, self.stuff))
101//!     }
102//!
103//!     fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError> {
104//!         let (flags, rest) = u8::decode(buffer)?;
105//!         let some_flag: bool = flags & 1 != 0;
106//!         let (values, rest) = if flags & 2 != 0 {
107//!             let (vec, rest) = <Vec<[u8; 32]>>::decode(rest)?;
108//!             (Some(vec), rest)
109//!         } else {
110//!             (None, rest)
111//!         };
112//!         let ((other, stuff), rest) = map_decode!(rest, [String, u64]);
113//!         Ok((
114//!             Self {
115//!                 some_flag,
116//!                 values,
117//!                 other,
118//!                 stuff,
119//!             },
120//!             rest,
121//!         ))
122//!     }
123//! }
124//!
125//! // Test values
126//! let foo = MyStruct {
127//!     some_flag: false,
128//!     values: None,
129//!     other: "hi".to_string(),
130//!     stuff: 42,
131//! };
132//!
133//! let bar = MyStruct {
134//!     some_flag: true,
135//!     values: Some(vec![[1; 32], [2; 32]]),
136//!     other: "yo".to_string(),
137//!     stuff: 0,
138//! };
139//!
140//! // Encode `foo` and `bar` to a buffer
141//! let buffer = to_encoded_bytes!(&foo, &bar);
142//!
143//! // With the above use of a flags byte, the empty value encodes to only one byte
144//! assert_eq!(
145//!     buffer.len(),
146//!     // flags + string + u64
147//!     (1 + 3 + 1) +
148//!     // "" + (values.len().encoded_size() + (values.len() * <[u8;32]>::encoded_size()) + ""
149//!     (1 + (1 + (2 * 32)) + 3 + 1)
150//! );
151//!
152//! // And decode directly to your own struct
153//! let (foo_dec, rest) = MyStruct::decode(&buffer)?;
154//! let (bar_dec, rest) = MyStruct::decode(&rest)?;
155//! // Ensure all bytes were used
156//! assert!(rest.is_empty());
157//! assert_eq!(foo_dec, foo);
158//! assert_eq!(bar_dec, bar);
159//! # Ok::<(), Box<dyn std::error::Error>>(())
160//! ```
161mod error;
162mod fixedwidth;
163pub use fixedwidth::{FixedWidthEncoding, FixedWidthU32, FixedWidthU64, FixedWidthUint};
164use std::{
165    any::type_name,
166    net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6},
167};
168
169pub use crate::error::{EncodingError, EncodingErrorKind};
170
171/// indicates a variable width unsigned integer fits in u16
172pub const U16_SIGNIFIER: u8 = 0xfd;
173/// indicates a variable width unsigned integer fits in u32
174pub const U32_SIGNIFIER: u8 = 0xfe;
175/// indicates a variable width unsigned integer fits in u64
176pub const U64_SIGNIFIER: u8 = 0xff;
177
178const U16_SIZE: usize = 2;
179const U32_SIZE: usize = 4;
180const U64_SIZE: usize = 8;
181
182/// Encoded size of a network port
183pub const PORT_ENCODED_SIZE: usize = 2;
184/// Encoded size of an ipv4 address
185pub const IPV4_ADDR_ENCODED_SIZE: usize = U32_SIZE;
186/// Encoded size of an ipv6 address
187pub const IPV6_ADDR_ENCODED_SIZE: usize = 16;
188/// Encoded size for a [`SocketAddrV4`], an ipv4 address plus port.
189pub const SOCKET_ADDR_V4_ENCODED_SIZE: usize = IPV4_ADDR_ENCODED_SIZE + PORT_ENCODED_SIZE;
190/// Encoded size for a [`SocketAddrV6`], an ipv6 address plus port.
191pub const SOCKET_ADDR_V6_ENCODED_SIZE: usize = IPV6_ADDR_ENCODED_SIZE + PORT_ENCODED_SIZE;
192
193/// A trait for building small and fast parsers and serializers.
194pub trait CompactEncoding<Decode: ?Sized = Self> {
195    /// The size in bytes required to encode `self`.
196    fn encoded_size(&self) -> Result<usize, EncodingError>;
197
198    /// Encode `self` into `buffer` returning the remainder of `buffer`.
199    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError>;
200
201    /// Decode a value from the given `buffer` of the type specified by the `Decode` type parameter
202    /// (which defaults to `Self`). Returns the decoded value and remaining undecoded bytes.
203    fn decode(buffer: &[u8]) -> Result<(Decode, &[u8]), EncodingError>
204    where
205        Decode: Sized;
206
207    /// Encode `self` into a `Vec<u8>`. This is just a helper method for creating a buffer and
208    /// encoding to it in one step.
209    /// ```
210    /// # use std::net::Ipv4Addr;
211    /// # use compact_encoding::CompactEncoding;
212    /// let foo: Ipv4Addr = "0.0.0.0".parse()?;
213    /// let mut buff = vec![0; foo.encoded_size()?];
214    /// foo.encode(&mut buff)?;
215    /// # Ok::<(), Box<dyn std::error::Error>>(())
216    /// ```
217    fn to_encoded_bytes(&self) -> Result<Box<[u8]>, EncodingError> {
218        let mut buff = self.create_buffer()?;
219        self.encode(&mut buff)?;
220        Ok(buff)
221    }
222    /// Create an empty buffer of the correct size for encoding `self` to. This is just a helper
223    /// method for: encoding to it in one step.
224    /// ```
225    /// # use std::net::Ipv4Addr;
226    /// # use compact_encoding::CompactEncoding;
227    /// let foo: Ipv4Addr = "0.0.0.0".parse()?;
228    /// vec![0; foo.encoded_size()?];
229    /// # Ok::<(), Box<dyn std::error::Error>>(())
230    /// ```
231    fn create_buffer(&self) -> Result<Box<[u8]>, EncodingError> {
232        Ok(vec![0; self.encoded_size()?].into_boxed_slice())
233    }
234
235    /// Like [`CompactEncoding::encode`] but also return the number of bytes encoded.
236    fn encode_with_len<'a>(
237        &self,
238        buffer: &'a mut [u8],
239    ) -> Result<(&'a mut [u8], usize), EncodingError> {
240        let before_len = buffer.len();
241        let rest = self.encode(buffer)?;
242        let num_encoded_bytes = before_len - rest.len();
243        Ok((rest, num_encoded_bytes))
244    }
245
246    /// Like [`CompactEncoding::decode`] but also return the number of bytes decoded.
247    fn decode_with_len(buffer: &[u8]) -> Result<(Decode, &[u8], usize), EncodingError>
248    where
249        Decode: Sized,
250    {
251        let (out, rest) = Self::decode(buffer)?;
252        Ok((out, rest, buffer.len() - rest.len()))
253    }
254}
255
256/// Implement this for type `T` to have `CompactEncoding` implemented for `Vec<T>`
257pub trait VecEncodable: CompactEncoding {
258    /// Calculate the resulting size in bytes of `vec`
259    fn vec_encoded_size(vec: &[Self]) -> Result<usize, EncodingError>
260    where
261        Self: Sized;
262
263    /// Encode `vec` to `buffer`
264    fn vec_encode<'a>(vec: &[Self], buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError>
265    where
266        Self: Sized,
267    {
268        encode_vec(vec, buffer)
269    }
270
271    /// Decode [`Vec<Self>`] from buffer
272    fn vec_decode(buffer: &[u8]) -> Result<(Vec<Self>, &[u8]), EncodingError>
273    where
274        Self: Sized,
275    {
276        decode_vec(buffer)
277    }
278}
279
280// NB: we DO want &Box<..> because we want the trait to work for boxed things, hence clippy::allow
281#[allow(clippy::borrowed_box)]
282/// Define this trait for `T` to get `impl Box<[T]> for CompactEncoding`
283pub trait BoxedSliceEncodable: CompactEncoding {
284    /// The encoded size in bytes
285    fn boxed_slice_encoded_size(boxed: &Box<[Self]>) -> Result<usize, EncodingError>
286    where
287        Self: Sized;
288
289    /// Encode `Box<[Self]>` to the buffer and return the remainder of the buffer
290    fn boxed_slice_encode<'a>(
291        vec: &Box<[Self]>,
292        buffer: &'a mut [u8],
293    ) -> Result<&'a mut [u8], EncodingError>
294    where
295        Self: Sized,
296    {
297        encode_vec(vec, buffer)
298    }
299
300    /// Decode [`Box<[Self]>`] from buffer
301    fn boxed_slice_decode(buffer: &[u8]) -> Result<(Box<[Self]>, &[u8]), EncodingError>
302    where
303        Self: Sized,
304    {
305        let (result, rest) = decode_vec(buffer)?;
306        Ok((result.into_boxed_slice(), rest))
307    }
308}
309
310#[macro_export]
311/// Given a list of [`CompactEncoding`] things, sum the result of calling
312/// [`CompactEncoding::encoded_size`] on all of them.
313/// Note this is macro is useful when your arguments have differing types.
314/// ```
315/// # use crate::compact_encoding::{sum_encoded_size, CompactEncoding};
316/// # use std::net::Ipv4Addr;
317/// let foo: Ipv4Addr = "0.0.0.0".parse()?;
318/// let bar = 42u64;
319/// let qux = "hello?";
320/// let result = sum_encoded_size!(foo, bar, qux);
321/// assert_eq!(result, 12);
322/// # Ok::<(), Box<dyn std::error::Error>>(())
323/// ```
324/// If you want to use this within a non-result context you can do
325/// ```
326/// # use crate::compact_encoding::{sum_encoded_size, CompactEncoding, EncodingError};
327/// let bar = 42u64;
328/// let result = (|| Ok::<usize, EncodingError>(sum_encoded_size!(bar)))().unwrap();
329/// assert_eq!(result, 1);
330/// ```
331macro_rules! sum_encoded_size {
332    ($($val:expr),+) => {{
333        0
334        $(
335            + $val.encoded_size()?
336        )*
337    }}
338}
339
340#[macro_export]
341/// Given a list of [`CompactEncoding`] things, create a zeroed buffer of the correct size for encoding.
342/// Note this is macro is useful when your arguments have differing types.
343/// ```
344/// # use crate::compact_encoding::{create_buffer, CompactEncoding};
345/// # use std::net::Ipv4Addr;
346/// let foo: Ipv4Addr = "0.0.0.0".parse()?;
347/// let bar = 42u64;
348/// let qux = "hello?";
349/// let buff = create_buffer!(foo, bar, qux);
350/// assert_eq!(buff.len(), 12);
351/// # Ok::<(), Box<dyn std::error::Error>>(())
352/// ```
353macro_rules! create_buffer {
354    ($($val:expr),+) => {{
355        let len = (
356            0
357            $(
358                + $val.encoded_size()?
359            )*
360        );
361        vec![0; len].into_boxed_slice()
362    }}
363}
364
365#[macro_export]
366/// Given a buffer and a list of [`CompactEncoding`] things, encode the arguments to the buffer.
367/// Note this is macro is useful when your arguments have differing types.
368/// ```
369/// # use crate::compact_encoding::{create_buffer, map_encode, CompactEncoding};
370/// let num = 42u64;
371/// let word = "yo";
372/// let mut buff = create_buffer!(num, word);
373/// let result = map_encode!(&mut buff, num, word);
374/// assert!(result.is_empty());
375/// assert_eq!(&*buff, &[42, 2, b'y', b'o']);
376/// # Ok::<(), Box<dyn std::error::Error>>(())
377/// ```
378macro_rules! map_encode {
379    ($buffer:expr$(,)*) => {
380        $buffer
381    };
382    // Base case: single field
383    ($buffer:expr, $field:expr) => {
384        $field.encode($buffer)?
385    };
386    // Recursive case: first field + rest
387    ($buffer:expr, $first:expr, $($rest:expr),+) => {{
388        let rest = $first.encode($buffer)?;
389        map_encode!(rest, $($rest),+)
390    }};
391}
392
393#[macro_export]
394/// Given a list of [`CompactEncoding`] things, encode the arguments to the buffer.
395/// Note this is macro is useful when your arguments have differing types.
396/// ```
397/// # use crate::compact_encoding::to_encoded_bytes;
398/// let result = to_encoded_bytes!(42u64, "yo");
399/// assert_eq!(&*result, &[42, 2, 121, 111]);
400/// # Ok::<(), Box<dyn std::error::Error>>(())
401/// ```
402macro_rules! to_encoded_bytes {
403    ($($val:expr),*) => {{
404        use $crate::{map_encode, create_buffer, CompactEncoding};
405        let mut buffer = create_buffer!($($val),*);
406        map_encode!(&mut buffer, $($val),*);
407        buffer
408    }}
409}
410
411#[macro_export]
412/// Decode a buffer to the list of types provided, returning the remaining buffer.
413/// It takes as arguments: `(&buffer, [type1, type2, type3, ...])`
414/// And returns: `((decoded_type1, decoded_type2, ...), remaining_buffer)`
415/// ```
416/// # use crate::compact_encoding::{to_encoded_bytes, map_decode};
417/// let buffer = to_encoded_bytes!(42u64, "yo");
418/// let ((number, word), remaining_buffer) = map_decode!(&buffer, [u64, String]);
419/// assert!(remaining_buffer.is_empty());
420/// assert_eq!(number, 42u64);
421/// assert_eq!(word, "yo");
422/// # Ok::<(), Box<dyn std::error::Error>>(())
423/// ```
424macro_rules! map_decode {
425    ($buffer:expr, [
426        $($field_type:ty),* $(,)?
427    ]) => {{
428        use $crate::CompactEncoding;
429        let mut current_buffer: &[u8] = $buffer;
430
431        // Decode each type into `result_tuple`
432        let result_tuple = (
433            $(
434                match <$field_type>::decode(&current_buffer)? {
435                    (value, new_buf) => {
436                        current_buffer = new_buf;
437                        value
438                    }
439                },
440            )*
441        );
442        (result_tuple, current_buffer)
443    }};
444}
445
446#[macro_export]
447/// Helper for mapping the first element of a two eleent tuple.
448/// This is useful for cleanly handling the result of CompactEncoding::decode.
449macro_rules! map_first {
450    ($res:expr, $f:expr) => {{
451        let (one, two) = $res;
452        let mapped = $f(one);
453        (mapped, two)
454    }};
455}
456
457#[macro_export]
458/// like [`map_first`] but the mapping should return a result.
459macro_rules! map_first_result {
460    ($res:expr, $f:expr) => {{
461        let (one, two) = $res;
462        let mapped = $f(one)?;
463        (mapped, two)
464    }};
465}
466
467/// Split a slice in two at `mid`. Returns encoding error when `mid` is out of bounds.
468pub fn get_slices_checked(buffer: &[u8], mid: usize) -> Result<(&[u8], &[u8]), EncodingError> {
469    buffer.split_at_checked(mid).ok_or_else(|| {
470        EncodingError::out_of_bounds(&format!(
471            "Could not split slice at [{mid}] slice.len() = [{}]",
472            buffer.len()
473        ))
474    })
475}
476
477/// Split a mutable slice into two mutable slices around `mid`.
478/// Returns encoding error when `mid` is out of bounds.
479pub fn get_slices_mut_checked(
480    buffer: &mut [u8],
481    mid: usize,
482) -> Result<(&mut [u8], &mut [u8]), EncodingError> {
483    let len = buffer.len();
484    buffer.split_at_mut_checked(mid).ok_or_else(|| {
485        EncodingError::out_of_bounds(&format!(
486            "Could not split mut slice at [{mid}] slice.len() = [{len}]"
487        ))
488    })
489}
490
491/// Get a slice as an array of size `N`. Errors when `slice.len() != N`.
492pub fn as_array<const N: usize>(buffer: &[u8]) -> Result<&[u8; N], EncodingError> {
493    let blen = buffer.len();
494    if blen != N {
495        return Err(EncodingError::out_of_bounds(&format!(
496            "Could get a [{N}] byte array from a slice of length [{blen}]"
497        )));
498    }
499    Ok(buffer.split_first_chunk::<N>().expect("checked above").0)
500}
501
502/// Get a slice as a mutable array of size `N`. Errors when `slice.len() != N`.
503pub fn as_array_mut<const N: usize>(buffer: &mut [u8]) -> Result<&mut [u8; N], EncodingError> {
504    let blen = buffer.len();
505    if blen != N {
506        return Err(EncodingError::out_of_bounds(&format!(
507            "Could get a [{N}] byte array from a slice of length [{blen}]"
508        )));
509    }
510    Ok(buffer
511        .split_first_chunk_mut::<N>()
512        .expect("checked above")
513        .0)
514}
515
516/// Write `source` to `buffer` and return the remainder of `buffer`.
517/// Errors when `N < buffer.len()`
518pub fn write_array<'a, const N: usize>(
519    source: &[u8; N],
520    buffer: &'a mut [u8],
521) -> std::result::Result<&'a mut [u8], EncodingError> {
522    let blen = buffer.len();
523    let Some((dest, rest)) = buffer.split_first_chunk_mut::<N>() else {
524        return Err(EncodingError::out_of_bounds(&format!(
525            "Could not write [{}] bytes to buffer of length [{}]",
526            N, blen
527        )));
528    };
529    dest.copy_from_slice(source);
530    Ok(rest)
531}
532
533/// split the first `N` bytes of `buffer` off and return them
534pub fn take_array<const N: usize>(
535    buffer: &[u8],
536) -> std::result::Result<([u8; N], &[u8]), EncodingError> {
537    let Some((out, rest)) = buffer.split_first_chunk::<N>() else {
538        return Err(EncodingError::out_of_bounds(&format!(
539            "Could not take [{}] bytes from buffer of length [{}]",
540            N,
541            buffer.len()
542        )));
543    };
544    Ok((*out, rest))
545}
546/// split the first `N` bytes of `buffer` off and return them
547pub fn take_array_mut<const N: usize>(
548    buffer: &mut [u8],
549) -> std::result::Result<(&mut [u8; N], &mut [u8]), EncodingError> {
550    let blen = buffer.len();
551    let Some((out, rest)) = buffer.split_first_chunk_mut::<N>() else {
552        return Err(EncodingError::out_of_bounds(&format!(
553            "Could not write [{}] bytes to buffer of length [{blen}]",
554            N,
555        )));
556    };
557    Ok((out, rest))
558}
559
560/// write `source` to `buffer` and return remaining buffer
561pub fn write_slice<'a>(source: &[u8], buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
562    let mid = source.len();
563    let (dest, rest) = get_slices_mut_checked(buffer, mid)?;
564    dest.copy_from_slice(source);
565    Ok(rest)
566}
567
568/// Helper to convert a vec to an array, and fail with an encoding error when needed
569pub fn bytes_fixed_from_vec<const N: usize>(value: &[u8]) -> Result<[u8; N], EncodingError> {
570    <[u8; N]>::try_from(value).map_err(|e| {
571        EncodingError::invalid_data(&format!(
572            "Could not covert slice with length [{}] to array of length [{}]. Error: [{e}]",
573            value.len(),
574            N
575        ))
576    })
577}
578
579fn encoded_size_str(value: &str) -> Result<usize, EncodingError> {
580    Ok(encoded_size_usize(value.len()) + value.len())
581}
582
583/// The number of bytes required to encode this number. Note this is always variable width.
584pub fn encoded_size_usize(val: usize) -> usize {
585    if val < U16_SIGNIFIER.into() {
586        1
587    } else if val <= 0xffff {
588        3
589    } else if val <= 0xffffffff {
590        5
591    } else {
592        9
593    }
594}
595
596/// The number of bytes required to encode this number.
597/// We only need this for u64 because all other uints can be converted to usize reliably.
598pub fn encoded_size_var_u64(val: u64) -> usize {
599    if val < U16_SIGNIFIER.into() {
600        1
601    } else if val <= 0xffff {
602        3
603    } else if val <= 0xffffffff {
604        5
605    } else {
606        9
607    }
608}
609
610/// Write `uint` to the start of `buffer` and return the remaining part of `buffer`.
611pub fn encode_var_u64(uint: u64, buffer: &mut [u8]) -> Result<&mut [u8], EncodingError> {
612    if uint < U16_SIGNIFIER.into() {
613        encode_u8(uint as u8, buffer)
614    } else if uint <= 0xffff {
615        let rest = write_array(&[U16_SIGNIFIER], buffer)?;
616        encode_u16(uint as u16, rest)
617    } else if uint <= 0xffffffff {
618        let rest = write_array(&[U32_SIGNIFIER], buffer)?;
619        encode_u32(uint as u32, rest)
620    } else {
621        let rest = write_array(&[U64_SIGNIFIER], buffer)?;
622        encode_u64(uint, rest)
623    }
624}
625
626/// Decode a `usize` from `buffer` and return the remaining bytes.
627/// This will fail, when we are decoding a `usize` on a usize = u32 machine for data that was originally encoded on a `usize = u64` machine whenever the value is over `u32::MAX`.
628pub fn decode_usize(buffer: &[u8]) -> Result<(usize, &[u8]), EncodingError> {
629    let ([first], rest) = take_array::<1>(buffer)?;
630    Ok(match first {
631        x if x < U16_SIGNIFIER => (x.into(), rest),
632        U16_SIGNIFIER => map_first!(decode_u16(rest)?, |x: u16| x.into()),
633        U32_SIGNIFIER => {
634            map_first_result!(decode_u32(rest)?, |val| usize::try_from(val)
635                .map_err(|_| EncodingError::overflow("Could not convert u32 to usize")))
636        }
637        _ => {
638            map_first_result!(decode_u64(rest)?, |val| usize::try_from(val)
639                .map_err(|_| EncodingError::overflow("Could not convert u64 to usize")))
640        }
641    })
642}
643
644/// Encoded a fixed sized array to a buffer, return the remainder of the buffer.
645/// Errors when `value.len() > buffer.len()`;
646/// ```
647/// # use compact_encoding::encode_bytes_fixed;
648/// let mut buffer = vec![0; 3];
649/// let rest = encode_bytes_fixed(&[4, 2], &mut buffer)?;
650/// assert_eq!(rest, &[0]);
651/// assert_eq!(buffer, &[4, 2, 0]);
652/// # Ok::<(), Box<dyn std::error::Error>>(())
653/// ```
654pub fn encode_bytes_fixed<'a, const N: usize>(
655    value: &[u8; N],
656    buffer: &'a mut [u8],
657) -> Result<&'a mut [u8], EncodingError> {
658    write_array(value, buffer)
659}
660
661/// Decode a fixed sized array from a buffer. Return the array and the remainder of the buffer.
662/// Errors when `buffer.len() < N`;
663/// ```
664/// # use compact_encoding::decode_bytes_fixed;
665/// let mut buffer = vec![1, 2, 3];
666/// let (arr, rest) = decode_bytes_fixed::<2>(&mut buffer)?;
667/// assert_eq!(arr, [1, 2]);
668/// assert_eq!(rest, &[3]);
669/// # Ok::<(), Box<dyn std::error::Error>>(())
670/// ```
671pub fn decode_bytes_fixed<const N: usize>(
672    buffer: &[u8],
673) -> Result<([u8; N], &[u8]), EncodingError> {
674    take_array(buffer)
675    //write_array(value, buffer)
676}
677
678fn decode_u16(buffer: &[u8]) -> Result<(u16, &[u8]), EncodingError> {
679    let (data, rest) = take_array::<2>(buffer)?;
680    Ok((u16::from_le_bytes(data), rest))
681}
682fn decode_u32(buffer: &[u8]) -> Result<(u32, &[u8]), EncodingError> {
683    let (data, rest) = take_array::<4>(buffer)?;
684    Ok((u32::from_le_bytes(data), rest))
685}
686fn decode_u64(buffer: &[u8]) -> Result<(u64, &[u8]), EncodingError> {
687    let (data, rest) = take_array::<8>(buffer)?;
688    Ok((u64::from_le_bytes(data), rest))
689}
690
691fn decode_u32_var(buffer: &[u8]) -> Result<(u32, &[u8]), EncodingError> {
692    let ([first], rest) = take_array::<1>(buffer)?;
693    Ok(match first {
694        x if x < U16_SIGNIFIER => (x.into(), rest),
695        U16_SIGNIFIER => {
696            let (val, rest) = decode_u16(rest)?;
697            (val.into(), rest)
698        }
699        _ => decode_u32(rest)?,
700    })
701}
702
703fn decode_u64_var(buffer: &[u8]) -> Result<(u64, &[u8]), EncodingError> {
704    let ([first], rest) = take_array::<1>(buffer)?;
705    Ok(match first {
706        x if x < U16_SIGNIFIER => (x.into(), rest),
707        U16_SIGNIFIER => map_first!(decode_u16(rest)?, |x: u16| x.into()),
708        U32_SIGNIFIER => map_first!(decode_u32(rest)?, |x: u32| x.into()),
709        _ => decode_u64(rest)?,
710    })
711}
712
713fn decode_buffer_vec(buffer: &[u8]) -> Result<(Vec<u8>, &[u8]), EncodingError> {
714    let (n_bytes, rest) = decode_usize(buffer)?;
715    let (out, rest) = get_slices_checked(rest, n_bytes)?;
716    Ok((out.to_vec(), rest))
717}
718
719fn decode_string(buffer: &[u8]) -> Result<(String, &[u8]), EncodingError> {
720    let (len, rest) = decode_usize(buffer)?;
721    let (str_buff, rest) = get_slices_checked(rest, len)?;
722    let out = String::from_utf8(str_buff.to_vec())
723        .map_err(|e| EncodingError::invalid_data(&format!("String is invalid UTF-8, {e}")))?;
724    Ok((out, rest))
725}
726
727fn encode_u8(val: u8, buffer: &mut [u8]) -> Result<&mut [u8], EncodingError> {
728    write_array(&val.to_le_bytes(), buffer)
729}
730fn encode_u16(val: u16, buffer: &mut [u8]) -> Result<&mut [u8], EncodingError> {
731    write_array(&val.to_le_bytes(), buffer)
732}
733fn encode_u32(val: u32, buffer: &mut [u8]) -> Result<&mut [u8], EncodingError> {
734    write_array(&val.to_le_bytes(), buffer)
735}
736fn encode_u64(val: u64, buffer: &mut [u8]) -> Result<&mut [u8], EncodingError> {
737    write_array(&val.to_le_bytes(), buffer)
738}
739
740/// Encode a `usize` in a variable width way
741pub fn encode_usize_var<'a>(
742    value: &usize,
743    buffer: &'a mut [u8],
744) -> Result<&'a mut [u8], EncodingError> {
745    if *value < U16_SIGNIFIER.into() {
746        encode_u8(*value as u8, buffer)
747    } else if *value <= 0xffff {
748        encode_u16(*value as u16, write_array(&[U16_SIGNIFIER], buffer)?)
749    } else if *value <= 0xffffffff {
750        let value = u32::try_from(*value).map_err(|e| {
751            EncodingError::overflow(&format!(
752                "count not covert usize [{value}] to u32. Error: [{e}]"
753            ))
754        })?;
755        encode_u32(value, write_array(&[U32_SIGNIFIER], buffer)?)
756    } else {
757        let value = u64::try_from(*value).map_err(|e| {
758            EncodingError::overflow(&format!(
759                "count not covert usize [{value}] to u64. Error: [{e}]"
760            ))
761        })?;
762        encode_u64(value, write_array(&[U64_SIGNIFIER], buffer)?)
763    }
764}
765
766fn encode_str<'a>(value: &str, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
767    let rest = encode_usize_var(&value.len(), buffer)?;
768    write_slice(value.as_bytes(), rest)
769}
770
771fn encode_buffer<'a>(value: &[u8], buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
772    let rest = encode_usize_var(&value.len(), buffer)?;
773    write_slice(value, rest)
774}
775
776impl<const N: usize> CompactEncoding for [u8; N] {
777    fn encoded_size(&self) -> Result<usize, EncodingError> {
778        Ok(N)
779    }
780
781    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
782        write_array(self, buffer)
783    }
784
785    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
786    where
787        Self: Sized,
788    {
789        take_array(buffer)
790    }
791}
792
793impl CompactEncoding for u8 {
794    fn encoded_size(&self) -> Result<usize, EncodingError> {
795        Ok(1)
796    }
797
798    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
799        write_array(&[*self], buffer)
800    }
801
802    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
803    where
804        Self: Sized,
805    {
806        let ([out], rest) = take_array::<1>(buffer)?;
807        Ok((out, rest))
808    }
809}
810
811impl CompactEncoding for u16 {
812    fn encoded_size(&self) -> Result<usize, EncodingError> {
813        Ok(U16_SIZE)
814    }
815
816    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
817        encode_u16(*self, buffer)
818    }
819
820    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
821    where
822        Self: Sized,
823    {
824        decode_u16(buffer)
825    }
826}
827
828// NB: we want u32 encoded and decoded as variable sized uint
829impl CompactEncoding for u32 {
830    fn encoded_size(&self) -> Result<usize, EncodingError> {
831        Ok(encoded_size_usize(*self as usize))
832    }
833
834    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
835        encode_usize_var(&(*self as usize), buffer)
836    }
837
838    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
839    where
840        Self: Sized,
841    {
842        decode_u32_var(buffer)
843    }
844}
845impl CompactEncoding for u64 {
846    fn encoded_size(&self) -> Result<usize, EncodingError> {
847        Ok(encoded_size_var_u64(*self))
848    }
849
850    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
851        encode_var_u64(*self, buffer)
852    }
853
854    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
855    where
856        Self: Sized,
857    {
858        decode_u64_var(buffer)
859    }
860}
861
862impl CompactEncoding for usize {
863    fn encoded_size(&self) -> Result<usize, EncodingError> {
864        Ok(encoded_size_usize(*self))
865    }
866
867    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
868        encode_usize_var(self, buffer)
869    }
870
871    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
872    where
873        Self: Sized,
874    {
875        decode_usize(buffer)
876    }
877}
878
879impl CompactEncoding for String {
880    fn encoded_size(&self) -> Result<usize, EncodingError> {
881        encoded_size_str(self)
882    }
883
884    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
885        encode_str(self, buffer)
886    }
887
888    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
889    where
890        Self: Sized,
891    {
892        decode_string(buffer)
893    }
894}
895
896impl CompactEncoding<String> for str {
897    fn encoded_size(&self) -> Result<usize, EncodingError> {
898        encoded_size_str(self)
899    }
900
901    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
902        encode_str(self, buffer)
903    }
904
905    fn decode(buffer: &[u8]) -> Result<(String, &[u8]), EncodingError> {
906        decode_string(buffer)
907    }
908}
909
910impl CompactEncoding for Vec<String> {
911    fn encoded_size(&self) -> Result<usize, EncodingError> {
912        let mut out = encoded_size_usize(self.len());
913        for s in self {
914            out += s.encoded_size()?;
915        }
916        Ok(out)
917    }
918
919    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
920        let mut rest = encode_usize_var(&self.len(), buffer)?;
921        for s in self {
922            rest = s.encode(rest)?;
923        }
924        Ok(rest)
925    }
926
927    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
928    where
929        Self: Sized,
930    {
931        let (len, mut rest) = decode_usize(buffer)?;
932        let mut out = Vec::with_capacity(len);
933        for _ in 0..len {
934            let result = String::decode(rest)?;
935            out.push(result.0);
936            rest = result.1;
937        }
938        Ok((out, rest))
939    }
940}
941
942impl CompactEncoding for Vec<u8> {
943    fn encoded_size(&self) -> Result<usize, EncodingError> {
944        Ok(encoded_size_usize(self.len()) + self.len())
945    }
946
947    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
948        encode_buffer(self, buffer)
949    }
950
951    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
952    where
953        Self: Sized,
954    {
955        decode_buffer_vec(buffer)
956    }
957}
958
959impl CompactEncoding for Ipv4Addr {
960    fn encoded_size(&self) -> std::result::Result<usize, EncodingError> {
961        Ok(U32_SIZE)
962    }
963
964    fn encode<'a>(&self, buffer: &'a mut [u8]) -> std::result::Result<&'a mut [u8], EncodingError> {
965        let Some((dest, rest)) = buffer.split_first_chunk_mut::<4>() else {
966            return Err(EncodingError::out_of_bounds(&format!(
967                "Colud not encode {}, not enough room in buffer",
968                type_name::<Self>()
969            )));
970        };
971        dest.copy_from_slice(&self.octets());
972        Ok(rest)
973    }
974
975    fn decode(buffer: &[u8]) -> std::result::Result<(Self, &[u8]), EncodingError>
976    where
977        Self: Sized,
978    {
979        let Some((dest, rest)) = buffer.split_first_chunk::<4>() else {
980            return Err(EncodingError::out_of_bounds(&format!(
981                "Colud not decode {}, buffer not big enough",
982                type_name::<Self>()
983            )));
984        };
985        Ok((Ipv4Addr::from(*dest), rest))
986    }
987}
988
989impl CompactEncoding for Ipv6Addr {
990    fn encoded_size(&self) -> std::result::Result<usize, EncodingError> {
991        Ok(IPV6_ADDR_ENCODED_SIZE)
992    }
993
994    /// ```
995    /// # use std::net::Ipv6Addr;
996    /// # use compact_encoding::CompactEncoding;
997    /// let addr: Ipv6Addr = "1:2:3::1".parse()?;
998    /// let buff = addr.to_encoded_bytes()?.to_vec();
999    /// assert_eq!(buff, vec![0, 1, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
1000    /// # Ok::<(), Box<dyn std::error::Error>>(())
1001    /// ```
1002    fn encode<'a>(&self, buffer: &'a mut [u8]) -> std::result::Result<&'a mut [u8], EncodingError> {
1003        let Some((dest, rest)) = buffer.split_first_chunk_mut::<16>() else {
1004            return Err(EncodingError::out_of_bounds(&format!(
1005                "Colud not encode {}, not enough room in buffer",
1006                type_name::<Self>()
1007            )));
1008        };
1009        dest.copy_from_slice(&self.octets());
1010        Ok(rest)
1011    }
1012
1013    fn decode(buffer: &[u8]) -> std::result::Result<(Self, &[u8]), EncodingError>
1014    where
1015        Self: Sized,
1016    {
1017        let Some((dest, rest)) = buffer.split_first_chunk::<16>() else {
1018            return Err(EncodingError::out_of_bounds(&format!(
1019                "Colud not decode {}, buffer not big enough",
1020                type_name::<Self>()
1021            )));
1022        };
1023        Ok((Ipv6Addr::from(*dest), rest))
1024    }
1025}
1026
1027fn encode_vec<'a, T: CompactEncoding + Sized>(
1028    vec: &[T],
1029    buffer: &'a mut [u8],
1030) -> Result<&'a mut [u8], EncodingError> {
1031    let mut rest = encode_usize_var(&vec.len(), buffer)?;
1032    for x in vec {
1033        rest = <T as CompactEncoding>::encode(x, rest)?;
1034    }
1035    Ok(rest)
1036}
1037
1038fn decode_vec<T: CompactEncoding + Sized>(buffer: &[u8]) -> Result<(Vec<T>, &[u8]), EncodingError> {
1039    let (len, mut rest) = decode_usize(buffer)?;
1040    let mut out = Vec::with_capacity(len);
1041    for _ in 0..len {
1042        let res = <T as CompactEncoding>::decode(rest)?;
1043        out.push(res.0);
1044        rest = res.1;
1045    }
1046    Ok((out, rest))
1047}
1048
1049impl<T: VecEncodable> CompactEncoding for Vec<T> {
1050    fn encoded_size(&self) -> Result<usize, EncodingError> {
1051        T::vec_encoded_size(self)
1052    }
1053
1054    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
1055        <T as VecEncodable>::vec_encode(self, buffer)
1056    }
1057
1058    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
1059    where
1060        Self: Sized,
1061    {
1062        <T as VecEncodable>::vec_decode(buffer)
1063    }
1064}
1065
1066/// Get the encoded size for a Vec with elements which have a fixed size encoding.
1067pub fn vec_encoded_size_for_fixed_sized_elements<T: CompactEncoding>(
1068    vec: &[T],
1069    element_encoded_size: usize,
1070) -> usize {
1071    encoded_size_usize(vec.len()) + (vec.len() * element_encoded_size)
1072}
1073
1074impl VecEncodable for u32 {
1075    fn vec_encoded_size(vec: &[Self]) -> Result<usize, EncodingError>
1076    where
1077        Self: Sized,
1078    {
1079        Ok(encoded_size_usize(vec.len()) + (vec.len() * 4))
1080    }
1081    /// Encode `vec` to `buffer`
1082    fn vec_encode<'a>(vec: &[Self], buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError>
1083    where
1084        Self: Sized,
1085    {
1086        let mut rest = encode_usize_var(&vec.len(), buffer)?;
1087        for x in vec {
1088            rest = encode_u32(*x, rest)?;
1089        }
1090        Ok(rest)
1091    }
1092
1093    /// Decode [`Vec<Self>`] from buffer
1094    fn vec_decode(buffer: &[u8]) -> Result<(Vec<Self>, &[u8]), EncodingError>
1095    where
1096        Self: Sized,
1097    {
1098        let (len, mut rest) = decode_usize(buffer)?;
1099        let mut out = Vec::with_capacity(len);
1100
1101        for _ in 0..len {
1102            let result = decode_u32(rest)?;
1103            out.push(result.0);
1104            rest = result.1;
1105        }
1106        Ok((out, rest))
1107    }
1108}
1109
1110impl<const N: usize> VecEncodable for [u8; N] {
1111    fn vec_encoded_size(vec: &[Self]) -> Result<usize, EncodingError>
1112    where
1113        Self: Sized,
1114    {
1115        Ok(encoded_size_usize(vec.len()) + (vec.len() * N))
1116    }
1117}
1118
1119impl BoxedSliceEncodable for u8 {
1120    fn boxed_slice_encoded_size(boxed: &Box<[Self]>) -> Result<usize, EncodingError>
1121    where
1122        Self: Sized,
1123    {
1124        Ok(encoded_size_usize(boxed.len()) + boxed.len())
1125    }
1126
1127    fn boxed_slice_encode<'a>(
1128        boxed: &Box<[Self]>,
1129        buffer: &'a mut [u8],
1130    ) -> Result<&'a mut [u8], EncodingError>
1131    where
1132        Self: Sized,
1133    {
1134        let rest = encode_usize_var(&boxed.len(), buffer)?;
1135        write_slice(boxed, rest)
1136    }
1137
1138    fn boxed_slice_decode(buffer: &[u8]) -> Result<(Box<[Self]>, &[u8]), EncodingError>
1139    where
1140        Self: Sized,
1141    {
1142        let (len, rest) = decode_usize(buffer)?;
1143        let (out, rest) = get_slices_checked(rest, len)?;
1144        Ok((out.into(), rest))
1145    }
1146}
1147
1148impl<T: BoxedSliceEncodable> CompactEncoding for Box<[T]> {
1149    fn encoded_size(&self) -> Result<usize, EncodingError> {
1150        T::boxed_slice_encoded_size(self)
1151    }
1152
1153    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
1154        <T as BoxedSliceEncodable>::boxed_slice_encode(self, buffer)
1155    }
1156
1157    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
1158    where
1159        Self: Sized,
1160    {
1161        <T as BoxedSliceEncodable>::boxed_slice_decode(buffer)
1162    }
1163}
1164
1165impl CompactEncoding for SocketAddrV4 {
1166    fn encoded_size(&self) -> Result<usize, EncodingError> {
1167        Ok(SOCKET_ADDR_V4_ENCODED_SIZE)
1168    }
1169
1170    /// ```
1171    /// # use std::net::SocketAddrV4;
1172    /// # use compact_encoding::CompactEncoding;
1173    /// let addr: SocketAddrV4 = "127.0.0.1:42".parse()?;
1174    /// let buff = addr.to_encoded_bytes()?.to_vec();
1175    /// assert_eq!(buff, vec![127, 0, 0, 1, 42, 0]);
1176    /// # Ok::<(), Box<dyn std::error::Error>>(())
1177    /// ```
1178    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
1179        let rest = self.ip().encode(buffer)?;
1180        encode_u16(self.port(), rest)
1181    }
1182
1183    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
1184    where
1185        Self: Sized,
1186    {
1187        let (ip, rest) = Ipv4Addr::decode(buffer)?;
1188        let (port, rest) = decode_u16(rest)?;
1189        Ok((SocketAddrV4::new(ip, port), rest))
1190    }
1191}
1192impl CompactEncoding for SocketAddrV6 {
1193    fn encoded_size(&self) -> Result<usize, EncodingError> {
1194        Ok(SOCKET_ADDR_V6_ENCODED_SIZE)
1195    }
1196
1197    /// ```
1198    /// # use std::net::SocketAddrV6;
1199    /// # use compact_encoding::CompactEncoding;
1200    /// let addr: SocketAddrV6 = "[1:2:3::1]:80".parse()?;
1201    /// let buff = addr.to_encoded_bytes()?.to_vec();
1202    /// assert_eq!(buff, vec![0, 1, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0]);
1203    /// # Ok::<(), Box<dyn std::error::Error>>(())
1204    /// ```
1205    fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
1206        let rest = self.ip().encode(buffer)?;
1207        encode_u16(self.port(), rest)
1208    }
1209
1210    fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
1211    where
1212        Self: Sized,
1213    {
1214        let (ip, rest) = Ipv6Addr::decode(buffer)?;
1215        let (port, rest) = decode_u16(rest)?;
1216        // TODO is this correct for flowinfo and scope_id?
1217        Ok((SocketAddrV6::new(ip, port, 0, 0), rest))
1218    }
1219}
1220
1221impl VecEncodable for SocketAddrV4 {
1222    fn vec_encoded_size(vec: &[Self]) -> Result<usize, EncodingError>
1223    where
1224        Self: Sized,
1225    {
1226        Ok(vec_encoded_size_for_fixed_sized_elements(
1227            vec,
1228            SOCKET_ADDR_V4_ENCODED_SIZE,
1229        ))
1230    }
1231}
1232
1233impl VecEncodable for SocketAddrV6 {
1234    fn vec_encoded_size(vec: &[Self]) -> Result<usize, EncodingError>
1235    where
1236        Self: Sized,
1237    {
1238        Ok(vec_encoded_size_for_fixed_sized_elements(
1239            vec,
1240            SOCKET_ADDR_V6_ENCODED_SIZE,
1241        ))
1242    }
1243}
1244
1245#[cfg(test)]
1246mod test {
1247    use super::*;
1248
1249    #[test]
1250    fn decode_buff_vec() -> Result<(), EncodingError> {
1251        let buf = &[1, 1];
1252        let (a, b) = decode_buffer_vec(buf)?;
1253        assert_eq!(a, &[1]);
1254        assert_eq!(b, &[]);
1255        Ok(())
1256    }
1257    macro_rules! check_usize_var_enc_dec {
1258        ($size:expr, $value:expr) => {
1259            let mut buffer = vec![0; encoded_size_usize($value)];
1260            assert_eq!(buffer.len(), $size);
1261            let remaining = encode_usize_var(&$value, &mut buffer)?;
1262            assert!(remaining.is_empty());
1263            let (result, rest) = decode_usize(&buffer)?;
1264            assert!(rest.is_empty());
1265            assert_eq!(result, $value);
1266        };
1267    }
1268
1269    #[test]
1270    fn usize_var_enc_dec() -> Result<(), EncodingError> {
1271        check_usize_var_enc_dec!(1, 42);
1272        check_usize_var_enc_dec!(1 + 2, 256);
1273        check_usize_var_enc_dec!(1 + 4, 65536);
1274        check_usize_var_enc_dec!(1 + 8, 4294967296);
1275
1276        Ok(())
1277    }
1278}