wasm_types/
flat_vector.rs1extern crate alloc;
24
25use wasm_bindgen::convert::{FromWasmAbi, IntoWasmAbi, OptionFromWasmAbi, OptionIntoWasmAbi};
26
27use alloc::vec::Vec;
28use core::{convert::From, ops::Deref};
29
30#[derive(Clone, Debug)]
31pub struct FlatVector<T>(Vec<T>);
32
33impl<T: FlatVectorElem> FlatVector<T> {
34 #[must_use]
35 pub fn from_bytes(data: Vec<u8>) -> Self {
36 let mut res: Vec<T> = Vec::with_capacity(data.len() / T::FLATTENED_SIZE);
37
38 let mut buf = Vec::with_capacity(T::FLATTENED_SIZE);
39
40 for x in data {
41 assert!(buf.len() < T::FLATTENED_SIZE);
42
43 buf.push(x);
44
45 if buf.len() >= T::FLATTENED_SIZE {
46 res.push(T::unflatten(buf));
47 buf = Vec::with_capacity(T::FLATTENED_SIZE);
48 }
49 }
50
51 assert_eq!(buf.len(), 0);
52
53 FlatVector(res)
54 }
55}
56
57pub trait FlatVectorElem {
58 const FLATTENED_SIZE: usize;
59 fn flatten(self) -> Vec<u8>;
60 fn unflatten(flat: Vec<u8>) -> Self;
61}
62
63impl<T> Deref for FlatVector<T> {
64 type Target = Vec<T>;
65
66 fn deref(&self) -> &Self::Target {
67 &self.0
68 }
69}
70
71impl<T> From<Vec<T>> for FlatVector<T> {
72 fn from(x: Vec<T>) -> Self {
73 FlatVector(x)
74 }
75}
76
77impl<T> From<FlatVector<T>> for Vec<T> {
78 fn from(x: FlatVector<T>) -> Self {
79 x.0
80 }
81}
82
83impl<'a, T> From<&'a FlatVector<T>> for &'a Vec<T> {
84 fn from(x: &'a FlatVector<T>) -> Self {
85 &x.0
86 }
87}
88
89impl<T> core::iter::IntoIterator for FlatVector<T> {
90 type Item = <Vec<T> as core::iter::IntoIterator>::Item;
91 type IntoIter = <Vec<T> as core::iter::IntoIterator>::IntoIter;
92 fn into_iter(self) -> Self::IntoIter {
93 self.0.into_iter()
94 }
95}
96
97impl<'a, T> core::iter::IntoIterator for &'a FlatVector<T> {
98 type Item = <&'a Vec<T> as core::iter::IntoIterator>::Item;
99 type IntoIter = <&'a Vec<T> as core::iter::IntoIterator>::IntoIter;
100 fn into_iter(self) -> Self::IntoIter {
101 self.0.iter()
102 }
103}
104
105impl<T> core::iter::FromIterator<T> for FlatVector<T> {
106 fn from_iter<I>(iter: I) -> FlatVector<T>
107 where
108 I: IntoIterator<Item = T>,
109 {
110 FlatVector(core::iter::FromIterator::from_iter(iter))
111 }
112}
113
114impl<T> core::default::Default for FlatVector<T> {
115 fn default() -> Self {
116 FlatVector(core::default::Default::default())
117 }
118}
119
120impl<T> core::iter::Extend<T> for FlatVector<T> {
121 fn extend<I>(&mut self, iter: I)
122 where
123 I: IntoIterator<Item = T>,
124 {
125 self.0.extend(iter);
126 }
127}
128
129impl<T> wasm_bindgen::describe::WasmDescribe for FlatVector<T> {
130 fn describe() {
131 <Vec<u8> as wasm_bindgen::describe::WasmDescribe>::describe();
132 }
133}
134
135impl<T: FlatVectorElem> FromWasmAbi for FlatVector<T> {
136 type Abi = <Vec<u8> as FromWasmAbi>::Abi;
137 unsafe fn from_abi(js: Self::Abi) -> Self {
138 let data: Vec<u8> = FromWasmAbi::from_abi(js);
139 let mut res: Vec<T> = Vec::with_capacity(data.len() / T::FLATTENED_SIZE);
140
141 let mut buf = Vec::with_capacity(T::FLATTENED_SIZE);
142 for x in data {
143 assert!(buf.len() < T::FLATTENED_SIZE);
144 buf.push(x);
145 if buf.len() >= T::FLATTENED_SIZE {
146 res.push(T::unflatten(buf));
147 buf = Vec::with_capacity(T::FLATTENED_SIZE);
148 }
149 }
150 assert_eq!(buf.len(), 0);
151 FlatVector(res)
152 }
153}
154
155impl<T: FlatVectorElem> OptionFromWasmAbi for FlatVector<T> {
156 fn is_none(x: &Self::Abi) -> bool {
157 <Vec<u8> as OptionFromWasmAbi>::is_none(x)
158 }
159}
160
161impl<T: FlatVectorElem> IntoWasmAbi for FlatVector<T> {
162 type Abi = <Vec<u8> as FromWasmAbi>::Abi;
163 fn into_abi(self) -> Self::Abi {
164 let mut data: Vec<u8> = Vec::with_capacity(self.0.len() * T::FLATTENED_SIZE);
165 for x in self.0 {
166 data.extend(x.flatten().into_iter());
167 }
168 IntoWasmAbi::into_abi(data)
169 }
170}
171
172impl<T: FlatVectorElem> OptionIntoWasmAbi for FlatVector<T> {
173 fn none() -> Self::Abi {
174 <Vec<u8> as OptionIntoWasmAbi>::none()
175 }
176}