packed_struct/
types_vec.rs

1//! Helpers for vectors of slice-packable structures
2
3use crate::internal_prelude::v1::*;
4
5use crate::{PackedStructSlice, PackingError, lib_get_mut_slice, lib_get_slice};
6
7/// This can only be used as a vector of structures that have a statically known size
8impl<T> PackedStructSlice for Vec<T> where T: PackedStructSlice {
9    fn pack_to_slice(&self, output: &mut [u8]) -> Result<(), PackingError> {
10        let expected_size = Self::packed_bytes_size(Some(self))?;
11        if output.len() != expected_size {
12            return Err(crate::PackingError::BufferSizeMismatch { expected: expected_size, actual: output.len() });
13        }
14
15        let size = T::packed_bytes_size(None)?;
16
17        for (i, item) in self.iter().enumerate() {
18            let item_out = lib_get_mut_slice(output, (i * size)..((i+1)*size))?;
19            item.pack_to_slice(item_out)?;
20        }
21
22        Ok(())
23    }
24
25    fn unpack_from_slice(src: &[u8]) -> Result<Self, PackingError> {
26        let item_size = T::packed_bytes_size(None)?;
27        if item_size == 0 || src.is_empty() { return Ok(vec![]); }
28        let modulo = src.len() % item_size;
29        if modulo != 0 {
30            return Err(crate::PackingError::BufferModMismatch { actual_size: src.len(), modulo_required: item_size });
31        }
32        let n = src.len() / item_size;
33
34        let mut vec = Vec::with_capacity(n);
35        for i in 0..n {
36            let item_src = lib_get_slice(src, (i*item_size)..((i+1)*item_size))?;
37            let item = T::unpack_from_slice(item_src)?;
38            vec.push(item);
39        }        
40
41        Ok(vec)
42    }
43
44    fn packed_bytes_size(opt_self: Option<&Self>) -> Result<usize, PackingError> {
45        match opt_self {
46            None => Err(PackingError::InstanceRequiredForSize),
47            Some(s) => {
48                Ok(s.len() * T::packed_bytes_size(None)?)
49            }
50        }
51    }
52}