ic_stable_memory/encoding/
dyn_size.rs1use candid::de::IDLDeserialize;
2use candid::utils::ArgumentDecoder;
3use candid::{CandidType, Deserialize, Result};
4
5pub trait AsDynSizeBytes {
20 fn as_dyn_size_bytes(&self) -> Vec<u8>;
25
26 fn from_dyn_size_bytes(buf: &[u8]) -> Self;
36}
37
38#[cfg(not(feature = "custom_dyn_encoding"))]
39use crate::encoding::AsFixedSizeBytes;
40
41#[cfg(not(feature = "custom_dyn_encoding"))]
42use crate::primitive::s_box::SBox;
43
44#[cfg(not(feature = "custom_dyn_encoding"))]
45impl<T: AsFixedSizeBytes> AsDynSizeBytes for T {
46 #[inline]
47 fn as_dyn_size_bytes(&self) -> Vec<u8> {
48 let mut v = vec![0u8; T::SIZE];
49 self.as_fixed_size_bytes(&mut v);
50
51 v
52 }
53
54 #[inline]
55 fn from_dyn_size_bytes(buf: &[u8]) -> Self {
56 Self::from_fixed_size_bytes(&buf[0..T::SIZE])
57 }
58}
59
60#[cfg(not(feature = "custom_dyn_encoding"))]
61impl AsDynSizeBytes for Vec<u8> {
62 #[inline]
63 fn as_dyn_size_bytes(&self) -> Vec<u8> {
64 let mut v = vec![0u8; usize::SIZE + self.len()];
65
66 self.len().as_fixed_size_bytes(&mut v[0..usize::SIZE]);
67 v[usize::SIZE..(usize::SIZE + self.len())].copy_from_slice(&self);
68
69 v
70 }
71
72 #[inline]
73 fn from_dyn_size_bytes(buf: &[u8]) -> Self {
74 let len = usize::from_fixed_size_bytes(&buf[0..usize::SIZE]);
75 let mut v = vec![0u8; len];
76
77 v.copy_from_slice(&buf[usize::SIZE..(usize::SIZE + len)]);
78
79 v
80 }
81}
82
83#[cfg(not(feature = "custom_dyn_encoding"))]
84impl AsDynSizeBytes for String {
85 #[inline]
86 fn as_dyn_size_bytes(&self) -> Vec<u8> {
87 let mut v = vec![0u8; usize::SIZE + self.len()];
88
89 self.len().as_fixed_size_bytes(&mut v[0..usize::SIZE]);
90 v[usize::SIZE..(usize::SIZE + self.len())].copy_from_slice(self.as_bytes());
91
92 v
93 }
94
95 #[inline]
96 fn from_dyn_size_bytes(buf: &[u8]) -> Self {
97 let len = usize::from_fixed_size_bytes(&buf[0..usize::SIZE]);
98 let mut v = vec![0u8; len];
99
100 v.copy_from_slice(&buf[usize::SIZE..(usize::SIZE + len)]);
101
102 String::from_utf8(v).unwrap()
103 }
104}
105
106pub fn candid_decode_args_allow_trailing<'a, Tuple>(bytes: &'a [u8]) -> Result<Tuple>
107where
108 Tuple: ArgumentDecoder<'a>,
109{
110 let mut de = IDLDeserialize::new(bytes)?;
111 let res = ArgumentDecoder::decode(&mut de)?;
112
113 Ok(res)
114}
115
116pub fn candid_decode_one_allow_trailing<'a, T>(bytes: &'a [u8]) -> Result<T>
117where
118 T: Deserialize<'a> + CandidType,
119{
120 let (res,) = candid_decode_args_allow_trailing(bytes)?;
121 Ok(res)
122}