1use core::ops::{Add, Div, Mul, Sub};
6
7use super::*;
8
9#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
11#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
12pub struct ATerm;
13
14impl TypeArray for ATerm {}
15
16#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
23#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
24pub struct TArr<V, A> {
25 first: V,
26 rest: A,
27}
28
29impl<V, A> TypeArray for TArr<V, A> {}
30
31#[macro_export]
44macro_rules! tarr {
45 () => ( $crate::ATerm );
46 ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
47 ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
48 ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
49 ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
50}
51
52impl Len for ATerm {
57 type Output = U0;
58 #[inline]
59 fn len(&self) -> Self::Output {
60 UTerm
61 }
62}
63
64impl<V, A> Len for TArr<V, A>
66where
67 A: Len,
68 Length<A>: Add<B1>,
69 Sum<Length<A>, B1>: Unsigned,
70{
71 type Output = Add1<Length<A>>;
72 #[inline]
73 fn len(&self) -> Self::Output {
74 self.rest.len() + B1
75 }
76}
77
78impl Add<ATerm> for ATerm {
83 type Output = ATerm;
84 #[inline]
85 fn add(self, _: ATerm) -> Self::Output {
86 ATerm
87 }
88}
89
90impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
91where
92 Al: Add<Ar>,
93 Vl: Add<Vr>,
94{
95 type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
96 #[inline]
97 fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {
98 TArr {
99 first: self.first + rhs.first,
100 rest: self.rest + rhs.rest,
101 }
102 }
103}
104
105impl Sub<ATerm> for ATerm {
110 type Output = ATerm;
111 #[inline]
112 fn sub(self, _: ATerm) -> Self::Output {
113 ATerm
114 }
115}
116
117impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
118where
119 Vl: Sub<Vr>,
120 Al: Sub<Ar>,
121{
122 type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
123 #[inline]
124 fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {
125 TArr {
126 first: self.first - rhs.first,
127 rest: self.rest - rhs.rest,
128 }
129 }
130}
131
132impl<Rhs> Mul<Rhs> for ATerm {
136 type Output = ATerm;
137 #[inline]
138 fn mul(self, _: Rhs) -> Self::Output {
139 ATerm
140 }
141}
142
143impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
144where
145 V: Mul<Rhs>,
146 A: Mul<Rhs>,
147 Rhs: Copy,
148{
149 type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
150 #[inline]
151 fn mul(self, rhs: Rhs) -> Self::Output {
152 TArr {
153 first: self.first * rhs,
154 rest: self.rest * rhs,
155 }
156 }
157}
158
159impl Mul<ATerm> for Z0 {
160 type Output = ATerm;
161 #[inline]
162 fn mul(self, _: ATerm) -> Self::Output {
163 ATerm
164 }
165}
166
167impl<U> Mul<ATerm> for PInt<U>
168where
169 U: Unsigned + NonZero,
170{
171 type Output = ATerm;
172 #[inline]
173 fn mul(self, _: ATerm) -> Self::Output {
174 ATerm
175 }
176}
177
178impl<U> Mul<ATerm> for NInt<U>
179where
180 U: Unsigned + NonZero,
181{
182 type Output = ATerm;
183 #[inline]
184 fn mul(self, _: ATerm) -> Self::Output {
185 ATerm
186 }
187}
188
189impl<V, A> Mul<TArr<V, A>> for Z0
190where
191 Z0: Mul<A>,
192{
193 type Output = TArr<Z0, Prod<Z0, A>>;
194 #[inline]
195 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
196 TArr {
197 first: Z0,
198 rest: self * rhs.rest,
199 }
200 }
201}
202
203impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
204where
205 U: Unsigned + NonZero,
206 PInt<U>: Mul<A> + Mul<V>,
207{
208 type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
209 #[inline]
210 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
211 TArr {
212 first: self * rhs.first,
213 rest: self * rhs.rest,
214 }
215 }
216}
217
218impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
219where
220 U: Unsigned + NonZero,
221 NInt<U>: Mul<A> + Mul<V>,
222{
223 type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
224 #[inline]
225 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
226 TArr {
227 first: self * rhs.first,
228 rest: self * rhs.rest,
229 }
230 }
231}
232
233impl<Rhs> Div<Rhs> for ATerm {
237 type Output = ATerm;
238 #[inline]
239 fn div(self, _: Rhs) -> Self::Output {
240 ATerm
241 }
242}
243
244impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
245where
246 V: Div<Rhs>,
247 A: Div<Rhs>,
248 Rhs: Copy,
249{
250 type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
251 #[inline]
252 fn div(self, rhs: Rhs) -> Self::Output {
253 TArr {
254 first: self.first / rhs,
255 rest: self.rest / rhs,
256 }
257 }
258}
259
260impl<Rhs> PartialDiv<Rhs> for ATerm {
264 type Output = ATerm;
265 #[inline]
266 fn partial_div(self, _: Rhs) -> Self::Output {
267 ATerm
268 }
269}
270
271impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
272where
273 V: PartialDiv<Rhs>,
274 A: PartialDiv<Rhs>,
275 Rhs: Copy,
276{
277 type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
278 #[inline]
279 fn partial_div(self, rhs: Rhs) -> Self::Output {
280 TArr {
281 first: self.first.partial_div(rhs),
282 rest: self.rest.partial_div(rhs),
283 }
284 }
285}
286
287use core::ops::Rem;
290
291impl<Rhs> Rem<Rhs> for ATerm {
292 type Output = ATerm;
293 #[inline]
294 fn rem(self, _: Rhs) -> Self::Output {
295 ATerm
296 }
297}
298
299impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
300where
301 V: Rem<Rhs>,
302 A: Rem<Rhs>,
303 Rhs: Copy,
304{
305 type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
306 #[inline]
307 fn rem(self, rhs: Rhs) -> Self::Output {
308 TArr {
309 first: self.first % rhs,
310 rest: self.rest % rhs,
311 }
312 }
313}
314
315use core::ops::Neg;
318
319impl Neg for ATerm {
320 type Output = ATerm;
321 #[inline]
322 fn neg(self) -> Self::Output {
323 ATerm
324 }
325}
326
327impl<V, A> Neg for TArr<V, A>
328where
329 V: Neg,
330 A: Neg,
331{
332 type Output = TArr<Negate<V>, Negate<A>>;
333 #[inline]
334 fn neg(self) -> Self::Output {
335 TArr {
336 first: -self.first,
337 rest: -self.rest,
338 }
339 }
340}