fuel_compression/
impls.rs1use super::traits::*;
4use crate::RegistryKey;
5use core::mem::MaybeUninit;
6use fuel_types::{
7 Address,
8 AssetId,
9 BlobId,
10 BlockHeight,
11 Bytes32,
12 ContractId,
13 Nonce,
14 Salt,
15};
16
17macro_rules! identity_compression {
18 ($t:ty) => {
19 impl Compressible for $t {
20 type Compressed = Self;
21 }
22
23 impl<Ctx> CompressibleBy<Ctx> for $t
24 where
25 Ctx: ContextError,
26 {
27 async fn compress_with(&self, _: &mut Ctx) -> Result<Self, Ctx::Error> {
28 Ok(*self)
29 }
30 }
31
32 impl<Ctx> DecompressibleBy<Ctx> for $t
33 where
34 Ctx: ContextError,
35 {
36 async fn decompress_with(
37 c: Self::Compressed,
38 _: &Ctx,
39 ) -> Result<Self, Ctx::Error> {
40 Ok(c)
41 }
42 }
43 };
44}
45
46identity_compression!(u8);
47identity_compression!(u16);
48identity_compression!(u32);
49identity_compression!(u64);
50identity_compression!(u128);
51
52identity_compression!(BlockHeight);
53identity_compression!(BlobId);
54identity_compression!(Bytes32);
55identity_compression!(Salt);
56identity_compression!(Nonce);
57
58impl Compressible for Address {
59 type Compressed = RegistryKey;
60}
61
62impl Compressible for ContractId {
63 type Compressed = RegistryKey;
64}
65
66impl Compressible for AssetId {
67 type Compressed = RegistryKey;
68}
69
70impl<const S: usize, T> Compressible for [T; S]
71where
72 T: Compressible,
73{
74 type Compressed = [T::Compressed; S];
75}
76
77impl<const S: usize, T, Ctx> CompressibleBy<Ctx> for [T; S]
78where
79 T: CompressibleBy<Ctx>,
80 Ctx: ContextError,
81{
82 #[allow(unsafe_code)]
83 async fn compress_with(&self, ctx: &mut Ctx) -> Result<Self::Compressed, Ctx::Error> {
84 let mut tmp: [MaybeUninit<T::Compressed>; S] =
87 unsafe { MaybeUninit::uninit().assume_init() };
88
89 let mut i = 0;
90 while i < self.len() {
91 match self[i].compress_with(ctx).await {
92 Ok(value) => {
93 tmp[i].write(value);
95 }
96 Err(e) => {
97 for initialized_item in tmp.iter_mut().take(i) {
99 unsafe {
101 initialized_item.assume_init_drop();
102 }
103 }
104 return Err(e);
105 }
106 }
107 i += 1;
108 }
109
110 let result = tmp.map(|v| unsafe { v.assume_init() });
113 Ok(result)
114 }
115}
116
117impl<const S: usize, T, Ctx> DecompressibleBy<Ctx> for [T; S]
118where
119 T: DecompressibleBy<Ctx>,
120 Ctx: ContextError,
121{
122 #[allow(unsafe_code)]
123 async fn decompress_with(c: Self::Compressed, ctx: &Ctx) -> Result<Self, Ctx::Error> {
124 let mut tmp: [MaybeUninit<T>; S] = unsafe { MaybeUninit::uninit().assume_init() };
127
128 for (i, c) in c.into_iter().enumerate() {
129 match T::decompress_with(c, ctx).await {
130 Ok(value) => {
131 tmp[i].write(value);
133 }
134 Err(e) => {
135 for initialized_item in tmp.iter_mut().take(i) {
137 unsafe {
139 initialized_item.assume_init_drop();
140 }
141 }
142 return Err(e);
143 }
144 }
145 }
146
147 let result = tmp.map(|v| unsafe { v.assume_init() });
149 Ok(result)
150 }
151}
152
153impl<T> Compressible for Vec<T>
154where
155 T: Compressible,
156{
157 type Compressed = Vec<T::Compressed>;
158}
159
160impl<T, Ctx> CompressibleBy<Ctx> for Vec<T>
161where
162 T: CompressibleBy<Ctx>,
163 Ctx: ContextError,
164{
165 async fn compress_with(&self, ctx: &mut Ctx) -> Result<Self::Compressed, Ctx::Error> {
166 let mut result = Vec::with_capacity(self.len());
167 for item in self {
168 result.push(item.compress_with(ctx).await?);
169 }
170 Ok(result)
171 }
172}
173
174impl<T, Ctx> DecompressibleBy<Ctx> for Vec<T>
175where
176 T: DecompressibleBy<Ctx>,
177 Ctx: ContextError,
178{
179 async fn decompress_with(c: Self::Compressed, ctx: &Ctx) -> Result<Self, Ctx::Error> {
180 let mut result = Vec::with_capacity(c.len());
181 for item in c {
182 result.push(T::decompress_with(item, ctx).await?);
183 }
184 Ok(result)
185 }
186}