ic_wire/bounded/packed_i16/
mod.rs1use crate::Error;
2use alloc::vec::Vec;
3use core::fmt;
4use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
5
6#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct PackedI16<const N: usize>(Vec<i16>);
13impl<const N: usize> PackedI16<N> {
14 pub fn new(values: Vec<i16>) -> Result<Self, Error> {
16 if values.len() > N {
17 Err(Error::Limit)
18 } else {
19 Ok(Self(values))
20 }
21 }
22 pub fn as_slice(&self) -> &[i16] {
24 &self.0
25 }
26 pub fn into_vec(self) -> Vec<i16> {
28 self.0
29 }
30}
31impl<const N: usize> Serialize for PackedI16<N> {
32 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
33 #[cfg(target_endian = "little")]
37 {
38 serializer.serialize_bytes(bytemuck::must_cast_slice(&self.0))
39 }
40 #[cfg(target_endian = "big")]
41 {
42 let mut bytes = Vec::new();
43 bytes
44 .try_reserve_exact(self.0.len() * 2)
45 .map_err(|_| serde::ser::Error::custom("allocation"))?;
46 bytes.extend(self.0.iter().flat_map(|value| value.to_le_bytes()));
47 serializer.serialize_bytes(&bytes)
48 }
49 }
50}
51impl<'de, const N: usize> Deserialize<'de> for PackedI16<N> {
52 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
53 struct Visitor<const N: usize>;
54 impl<const N: usize> de::Visitor<'_> for Visitor<N> {
55 type Value = PackedI16<N>;
56 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 f.write_str("bounded packed little-endian i16 words")
58 }
59 fn visit_bytes<E: de::Error>(self, bytes: &[u8]) -> Result<Self::Value, E> {
60 if !bytes.len().is_multiple_of(2) || bytes.len() / 2 > N {
64 return Err(E::custom("invalid packed length"));
65 }
66 let mut values = Vec::new();
67 values
68 .try_reserve_exact(bytes.len() / 2)
69 .map_err(|_| E::custom("allocation"))?;
70 values.extend(
71 bytes
72 .as_chunks::<2>()
73 .0
74 .iter()
75 .map(|word| i16::from_le_bytes(*word)),
76 );
77 Ok(PackedI16(values))
78 }
79 }
80 deserializer.deserialize_bytes(Visitor::<N>)
81 }
82}