jam_types/
fixed_vec.rs

1use super::*;
2use bounded_collections::Get;
3use core::fmt;
4use scale::{decode_vec_with_len, ConstEncodedLen, Error as DecodeError, Output};
5
6/// Trait for vector types which have a bounded length allowing element-wise transformation.
7pub trait BoundedMap<T, N: Get<u32>> {
8	/// Element-wise transformation of items using the given function.
9	///
10	/// - `f`: The transformation function.
11	///
12	/// Returns a new instance with all elements transformed using the function `f`.
13	fn map<U>(self, f: impl FnMut(T) -> U) -> BoundedVec<U, N>;
14	/// Element-wise transformation of item-references using the given function.
15	///
16	/// - `f`: The transformation function.
17	///
18	/// Returns a new instance with all element-references transformed using the function `f`.
19	fn map_ref<U>(&self, f: impl FnMut(&T) -> U) -> BoundedVec<U, N>;
20	/// Fallible element-wise transformation of items using the given function.
21	///
22	/// - `f`: The transformation function.
23	///
24	/// Returns a new instance with all elements transformed using the function `f`, or
25	/// `Err` if any invocation of `f` resulted in error.
26	fn try_map<U, E>(self, f: impl FnMut(T) -> Result<U, E>) -> Result<BoundedVec<U, N>, E>;
27	/// Fallible element-wise transformation of item-references using the given function.
28	///
29	/// - `f`: The transformation function.
30	///
31	/// Returns a new instance with all element-references transformed using the function `f`, or
32	/// `Err` if any invocation of `f` resulted in error.
33	fn try_map_ref<U, E>(&self, f: impl FnMut(&T) -> Result<U, E>) -> Result<BoundedVec<U, N>, E>;
34}
35impl<T, N: Get<u32>> BoundedMap<T, N> for BoundedVec<T, N> {
36	fn map<U>(self, f: impl FnMut(T) -> U) -> BoundedVec<U, N> {
37		BoundedVec::truncate_from(self.into_iter().map(f).collect::<Vec<_>>())
38	}
39	fn map_ref<U>(&self, f: impl FnMut(&T) -> U) -> BoundedVec<U, N> {
40		BoundedVec::truncate_from(self.iter().map(f).collect::<Vec<_>>())
41	}
42	fn try_map<U, E>(self, f: impl FnMut(T) -> Result<U, E>) -> Result<BoundedVec<U, N>, E> {
43		self.into_iter()
44			.map(f)
45			.collect::<Result<Vec<_>, E>>()
46			.map(BoundedVec::truncate_from)
47	}
48	fn try_map_ref<U, E>(&self, f: impl FnMut(&T) -> Result<U, E>) -> Result<BoundedVec<U, N>, E> {
49		self.iter().map(f).collect::<Result<Vec<_>, E>>().map(BoundedVec::truncate_from)
50	}
51}
52
53/// Vector type with a fixed length.
54///
55/// Can be used similarly to an array but which stores its elements on the heap.
56#[derive(Clone)]
57pub struct FixedVec<T, N: Get<u32>>(BoundedVec<T, N>);
58impl<T, N: Get<u32>> FixedVec<T, N> {
59	pub fn new(t: T) -> Self
60	where
61		T: Clone,
62	{
63		Self::from_fn(|_| t.clone())
64	}
65	pub fn from_fn(f: impl FnMut(usize) -> T) -> Self {
66		Self(BoundedVec::truncate_from((0..N::get() as usize).map(f).collect::<Vec<T>>()))
67	}
68	pub fn get(&self, i: usize) -> Option<&T> {
69		if i < N::get() as usize {
70			Some(&self.0[i])
71		} else {
72			None
73		}
74	}
75	pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
76		if i < N::get() as usize {
77			Some(&mut self.0[i])
78		} else {
79			None
80		}
81	}
82	pub fn len(&self) -> usize {
83		N::get() as usize
84	}
85	pub fn is_empty(&self) -> bool {
86		N::get() == 0
87	}
88	pub fn iter(&self) -> core::slice::Iter<T> {
89		self.0.iter()
90	}
91	pub fn iter_mut(&mut self) -> core::slice::IterMut<T> {
92		self.0.iter_mut()
93	}
94	pub fn map<U>(self, f: impl FnMut(T) -> U) -> FixedVec<U, N> {
95		FixedVec(BoundedVec::truncate_from(self.0.into_iter().map(f).collect::<Vec<_>>()))
96	}
97	pub fn map_ref<U>(&self, f: impl FnMut(&T) -> U) -> FixedVec<U, N> {
98		FixedVec(BoundedVec::truncate_from(self.0.iter().map(f).collect::<Vec<_>>()))
99	}
100	pub fn to_bounded(self) -> BoundedVec<T, N> {
101		self.0
102	}
103	pub fn to_vec(self) -> Vec<T> {
104		self.0.into()
105	}
106	pub fn into_vec(self) -> Vec<T> {
107		self.0.into()
108	}
109	pub fn truncate_into_vec(self, len: usize) -> Vec<T> {
110		let mut v = self.into_vec();
111		v.truncate(len);
112		v
113	}
114	pub fn slide(&mut self, index: usize, insert_at: usize) {
115		self.0.slide(index, insert_at);
116	}
117	pub fn force_insert_keep_left(&mut self, index: usize, element: T) -> Result<Option<T>, T> {
118		self.0.force_insert_keep_left(index, element)
119	}
120	pub fn force_insert_keep_right(&mut self, index: usize, element: T) -> Result<Option<T>, T> {
121		self.0.force_insert_keep_right(index, element)
122	}
123	pub fn force_push(&mut self, element: T) {
124		self.0.force_push(element);
125	}
126	pub fn swap(&mut self, a: usize, b: usize) {
127		self.0.as_mut().swap(a, b);
128	}
129	pub fn as_ptr(&self) -> *const T {
130		self.0.as_ptr()
131	}
132	pub fn as_mut_ptr(&mut self) -> *mut T {
133		self.0.as_mut().as_mut_ptr()
134	}
135}
136
137impl<T: Encode, N: Get<u32>> Encode for FixedVec<T, N> {
138	fn size_hint(&self) -> usize {
139		self.0.size_hint() - 1
140	}
141	fn encode_to<D: Output + ?Sized>(&self, dest: &mut D) {
142		for t in self.0.iter() {
143			t.encode_to(dest);
144		}
145	}
146}
147
148impl<T: fmt::Debug, N: Get<u32>> fmt::Debug for FixedVec<T, N> {
149	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150		match self.0.len() {
151			0 => write!(f, "[]"),
152			_ => {
153				write!(f, "[{:?}", self.0[0])?;
154				for i in 1..self.len() {
155					write!(f, ", {:?}", self.0[i])?;
156				}
157				write!(f, "]")
158			},
159		}
160	}
161}
162
163impl<T: ConstEncodedLen, N: Get<u32>> scale::ConstEncodedLen for FixedVec<T, N> {}
164
165impl<T: fmt::Display, N: Get<u32>> fmt::Display for FixedVec<T, N> {
166	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167		match self.0.len() {
168			0 => write!(f, "[]"),
169			_ => {
170				write!(f, "[{}", self.0[0])?;
171				for i in 1..self.len() {
172					write!(f, ", {}", self.0[i])?;
173				}
174				write!(f, "]")
175			},
176		}
177	}
178}
179
180impl<T: Decode, N: Get<u32>> Decode for FixedVec<T, N> {
181	fn decode<I: scale::Input>(input: &mut I) -> Result<Self, DecodeError> {
182		Ok(Self(BoundedVec::truncate_from(decode_vec_with_len(input, N::get() as usize)?)))
183	}
184}
185
186impl<T: MaxEncodedLen, N: Get<u32>> MaxEncodedLen for FixedVec<T, N> {
187	fn max_encoded_len() -> usize {
188		T::max_encoded_len() * N::get() as usize
189	}
190}
191
192impl<T: Eq, N: Get<u32>> Eq for FixedVec<T, N> where T: Eq {}
193impl<T: PartialEq, N: Get<u32>> PartialEq for FixedVec<T, N> {
194	fn eq(&self, other: &Self) -> bool {
195		self.0[..] == other.0[..]
196	}
197}
198impl<T: Default, N: Get<u32>> Default for FixedVec<T, N> {
199	fn default() -> Self {
200		Self::from_fn(|_| T::default())
201	}
202}
203impl<T, N: Get<u32>> AsRef<[T]> for FixedVec<T, N> {
204	fn as_ref(&self) -> &[T] {
205		&self.0[..]
206	}
207}
208impl<T, N: Get<u32>> AsMut<[T]> for FixedVec<T, N> {
209	fn as_mut(&mut self) -> &mut [T] {
210		&mut self.0[..]
211	}
212}
213impl<T, N: Get<u32>> core::ops::Index<usize> for FixedVec<T, N> {
214	type Output = T;
215	fn index(&self, i: usize) -> &T {
216		&self.0[i]
217	}
218}
219impl<T, N: Get<u32>> core::ops::IndexMut<usize> for FixedVec<T, N> {
220	fn index_mut(&mut self, i: usize) -> &mut T {
221		&mut self.0[i]
222	}
223}
224impl<T, N: Get<u32>> core::ops::Index<core::ops::Range<usize>> for FixedVec<T, N> {
225	type Output = [T];
226
227	fn index(&self, index: core::ops::Range<usize>) -> &Self::Output {
228		&self.0[index]
229	}
230}
231impl<T, N: Get<u32>> core::ops::IndexMut<core::ops::Range<usize>> for FixedVec<T, N> {
232	fn index_mut(&mut self, index: core::ops::Range<usize>) -> &mut Self::Output {
233		&mut self.0[index]
234	}
235}
236impl<T, N: Get<u32>> core::ops::Index<core::ops::RangeFull> for FixedVec<T, N> {
237	type Output = [T];
238
239	fn index(&self, index: core::ops::RangeFull) -> &Self::Output {
240		&self.0[index]
241	}
242}
243impl<T, N: Get<u32>> core::ops::IndexMut<core::ops::RangeFull> for FixedVec<T, N> {
244	fn index_mut(&mut self, index: core::ops::RangeFull) -> &mut Self::Output {
245		&mut self.0[index]
246	}
247}
248impl<T, N: Get<u32>> From<FixedVec<T, N>> for Vec<T> {
249	fn from(s: FixedVec<T, N>) -> Vec<T> {
250		s.to_vec()
251	}
252}
253impl<T, N: Get<u32>> TryFrom<Vec<T>> for FixedVec<T, N> {
254	type Error = ();
255	fn try_from(v: Vec<T>) -> Result<Self, ()> {
256		if v.len() != N::get() as usize {
257			panic!("Invalid length");
258		}
259		Ok(Self(BoundedVec::truncate_from(v)))
260	}
261}
262impl<T, N: Get<u32>> From<FixedVec<T, N>> for BoundedVec<T, N> {
263	fn from(s: FixedVec<T, N>) -> BoundedVec<T, N> {
264		s.0
265	}
266}
267impl<T, N: Get<u32>> TryFrom<BoundedVec<T, N>> for FixedVec<T, N> {
268	type Error = ();
269	fn try_from(v: BoundedVec<T, N>) -> Result<Self, ()> {
270		if v.len() != N::get() as usize {
271			return Err(())
272		}
273		Ok(Self(v))
274	}
275}