1use core::ops::{Add, Div, Mul, Sub};
6#[cfg(feature = "derive_scale")]
7use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
8
9use super::*;
10
11#[cfg_attr(
13 feature = "derive_scale",
14 derive(scale_info::TypeInfo, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen)
15)]
16#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
17pub struct ATerm;
18
19impl TypeArray for ATerm {}
20
21#[cfg_attr(
28 feature = "derive_scale",
29 derive(scale_info::TypeInfo, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen)
30)]
31#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
32pub struct TArr<V, A> {
33 first: V,
34 rest: A,
35}
36
37impl<V, A> TypeArray for TArr<V, A> {}
38
39#[macro_export]
52macro_rules! tarr {
53 () => ( $crate::ATerm );
54 ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
55 ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
56 ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
57 ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
58}
59
60impl Len for ATerm {
65 type Output = U0;
66 #[inline]
67 fn len(&self) -> Self::Output {
68 UTerm
69 }
70}
71
72impl<V, A> Len for TArr<V, A>
74where
75 A: Len,
76 Length<A>: Add<B1>,
77 Sum<Length<A>, B1>: Unsigned,
78{
79 type Output = Add1<Length<A>>;
80 #[inline]
81 fn len(&self) -> Self::Output {
82 self.rest.len() + B1
83 }
84}
85
86impl Add<ATerm> for ATerm {
91 type Output = ATerm;
92 #[inline]
93 fn add(self, _: ATerm) -> Self::Output {
94 ATerm
95 }
96}
97
98impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
99where
100 Al: Add<Ar>,
101 Vl: Add<Vr>,
102{
103 type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
104 #[inline]
105 fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {
106 TArr {
107 first: self.first + rhs.first,
108 rest: self.rest + rhs.rest,
109 }
110 }
111}
112
113impl Sub<ATerm> for ATerm {
118 type Output = ATerm;
119 #[inline]
120 fn sub(self, _: ATerm) -> Self::Output {
121 ATerm
122 }
123}
124
125impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
126where
127 Vl: Sub<Vr>,
128 Al: Sub<Ar>,
129{
130 type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
131 #[inline]
132 fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {
133 TArr {
134 first: self.first - rhs.first,
135 rest: self.rest - rhs.rest,
136 }
137 }
138}
139
140impl<Rhs> Mul<Rhs> for ATerm {
144 type Output = ATerm;
145 #[inline]
146 fn mul(self, _: Rhs) -> Self::Output {
147 ATerm
148 }
149}
150
151impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
152where
153 V: Mul<Rhs>,
154 A: Mul<Rhs>,
155 Rhs: Copy,
156{
157 type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
158 #[inline]
159 fn mul(self, rhs: Rhs) -> Self::Output {
160 TArr {
161 first: self.first * rhs,
162 rest: self.rest * rhs,
163 }
164 }
165}
166
167impl Mul<ATerm> for Z0 {
168 type Output = ATerm;
169 #[inline]
170 fn mul(self, _: ATerm) -> Self::Output {
171 ATerm
172 }
173}
174
175impl<U> Mul<ATerm> for PInt<U>
176where
177 U: Unsigned + NonZero,
178{
179 type Output = ATerm;
180 #[inline]
181 fn mul(self, _: ATerm) -> Self::Output {
182 ATerm
183 }
184}
185
186impl<U> Mul<ATerm> for NInt<U>
187where
188 U: Unsigned + NonZero,
189{
190 type Output = ATerm;
191 #[inline]
192 fn mul(self, _: ATerm) -> Self::Output {
193 ATerm
194 }
195}
196
197impl<V, A> Mul<TArr<V, A>> for Z0
198where
199 Z0: Mul<A>,
200{
201 type Output = TArr<Z0, Prod<Z0, A>>;
202 #[inline]
203 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
204 TArr {
205 first: Z0,
206 rest: self * rhs.rest,
207 }
208 }
209}
210
211impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
212where
213 U: Unsigned + NonZero,
214 PInt<U>: Mul<A> + Mul<V>,
215{
216 type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
217 #[inline]
218 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
219 TArr {
220 first: self * rhs.first,
221 rest: self * rhs.rest,
222 }
223 }
224}
225
226impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
227where
228 U: Unsigned + NonZero,
229 NInt<U>: Mul<A> + Mul<V>,
230{
231 type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
232 #[inline]
233 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
234 TArr {
235 first: self * rhs.first,
236 rest: self * rhs.rest,
237 }
238 }
239}
240
241impl<Rhs> Div<Rhs> for ATerm {
245 type Output = ATerm;
246 #[inline]
247 fn div(self, _: Rhs) -> Self::Output {
248 ATerm
249 }
250}
251
252impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
253where
254 V: Div<Rhs>,
255 A: Div<Rhs>,
256 Rhs: Copy,
257{
258 type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
259 #[inline]
260 fn div(self, rhs: Rhs) -> Self::Output {
261 TArr {
262 first: self.first / rhs,
263 rest: self.rest / rhs,
264 }
265 }
266}
267
268impl<Rhs> PartialDiv<Rhs> for ATerm {
272 type Output = ATerm;
273 #[inline]
274 fn partial_div(self, _: Rhs) -> Self::Output {
275 ATerm
276 }
277}
278
279impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
280where
281 V: PartialDiv<Rhs>,
282 A: PartialDiv<Rhs>,
283 Rhs: Copy,
284{
285 type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
286 #[inline]
287 fn partial_div(self, rhs: Rhs) -> Self::Output {
288 TArr {
289 first: self.first.partial_div(rhs),
290 rest: self.rest.partial_div(rhs),
291 }
292 }
293}
294
295use core::ops::Rem;
298
299impl<Rhs> Rem<Rhs> for ATerm {
300 type Output = ATerm;
301 #[inline]
302 fn rem(self, _: Rhs) -> Self::Output {
303 ATerm
304 }
305}
306
307impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
308where
309 V: Rem<Rhs>,
310 A: Rem<Rhs>,
311 Rhs: Copy,
312{
313 type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
314 #[inline]
315 fn rem(self, rhs: Rhs) -> Self::Output {
316 TArr {
317 first: self.first % rhs,
318 rest: self.rest % rhs,
319 }
320 }
321}
322
323use core::ops::Neg;
326
327impl Neg for ATerm {
328 type Output = ATerm;
329 #[inline]
330 fn neg(self) -> Self::Output {
331 ATerm
332 }
333}
334
335impl<V, A> Neg for TArr<V, A>
336where
337 V: Neg,
338 A: Neg,
339{
340 type Output = TArr<Negate<V>, Negate<A>>;
341 #[inline]
342 fn neg(self) -> Self::Output {
343 TArr {
344 first: -self.first,
345 rest: -self.rest,
346 }
347 }
348}