1use crate::traits::{Bounded, One, Zero};
21use codec::{Compact, CompactAs, Decode, DecodeWithMemTracking, Encode, HasCompact, MaxEncodedLen};
22use core::{
23 fmt::Display,
24 marker::PhantomData,
25 ops::{
26 Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem,
27 RemAssign, Shl, Shr, Sub, SubAssign,
28 },
29};
30use num_traits::{
31 CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
32 Num, NumCast, PrimInt, Saturating, ToPrimitive,
33};
34use scale_info::{StaticTypeInfo, TypeInfo};
35use sp_core::Get;
36
37#[cfg(feature = "serde")]
38use serde::{Deserialize, Serialize};
39
40#[derive(Encode, Decode, DecodeWithMemTracking, Debug, MaxEncodedLen)]
45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
46pub struct TypeWithDefault<T, D: Get<T>>(T, PhantomData<D>);
47
48impl<T, D: Get<T>> TypeWithDefault<T, D> {
49 fn new(value: T) -> Self {
50 Self(value, PhantomData)
51 }
52}
53
54impl<T: StaticTypeInfo, D: Get<T> + 'static> TypeInfo for TypeWithDefault<T, D> {
58 type Identity = Self;
59
60 fn type_info() -> scale_info::Type {
61 T::type_info()
62 }
63}
64
65impl<T: Clone, D: Get<T>> Clone for TypeWithDefault<T, D> {
66 fn clone(&self) -> Self {
67 Self(self.0.clone(), PhantomData)
68 }
69}
70
71impl<T: Copy, D: Get<T>> Copy for TypeWithDefault<T, D> {}
72
73impl<T: PartialEq, D: Get<T>> PartialEq for TypeWithDefault<T, D> {
74 fn eq(&self, other: &Self) -> bool {
75 self.0 == other.0
76 }
77}
78
79impl<T: Eq, D: Get<T>> Eq for TypeWithDefault<T, D> {}
80
81impl<T: PartialOrd, D: Get<T>> PartialOrd for TypeWithDefault<T, D> {
82 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
83 self.0.partial_cmp(&other.0)
84 }
85}
86
87impl<T: Ord, D: Get<T>> Ord for TypeWithDefault<T, D> {
88 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
89 self.0.cmp(&other.0)
90 }
91}
92
93impl<T, D: Get<T>> Deref for TypeWithDefault<T, D> {
94 type Target = T;
95 fn deref(&self) -> &Self::Target {
96 &self.0
97 }
98}
99
100impl<T, D: Get<T>> Default for TypeWithDefault<T, D> {
101 fn default() -> Self {
102 Self::new(D::get())
103 }
104}
105
106impl<T: CheckedNeg, D: Get<T>> CheckedNeg for TypeWithDefault<T, D> {
107 fn checked_neg(&self) -> Option<Self> {
108 self.0.checked_neg().map(Self::new)
109 }
110}
111
112impl<T: CheckedRem, D: Get<T>> CheckedRem for TypeWithDefault<T, D> {
113 fn checked_rem(&self, rhs: &Self) -> Option<Self> {
114 self.0.checked_rem(&rhs.0).map(Self::new)
115 }
116}
117
118impl<T: CheckedShr, D: Get<T>> CheckedShr for TypeWithDefault<T, D> {
119 fn checked_shr(&self, n: u32) -> Option<Self> {
120 self.0.checked_shr(n).map(Self::new)
121 }
122}
123
124impl<T: CheckedShl, D: Get<T>> CheckedShl for TypeWithDefault<T, D> {
125 fn checked_shl(&self, n: u32) -> Option<Self> {
126 self.0.checked_shl(n).map(Self::new)
127 }
128}
129
130impl<T: Rem<Output = T>, D: Get<T>> Rem for TypeWithDefault<T, D> {
131 type Output = Self;
132 fn rem(self, rhs: Self) -> Self {
133 Self::new(self.0 % rhs.0)
134 }
135}
136
137impl<T: Rem<u32, Output = T>, D: Get<T>> Rem<u32> for TypeWithDefault<T, D> {
138 type Output = Self;
139 fn rem(self, rhs: u32) -> Self {
140 Self::new(self.0 % (rhs.into()))
141 }
142}
143
144impl<T: Shr<u32, Output = T>, D: Get<T>> Shr<u32> for TypeWithDefault<T, D> {
145 type Output = Self;
146 fn shr(self, rhs: u32) -> Self {
147 Self::new(self.0 >> rhs)
148 }
149}
150
151impl<T: Shr<usize, Output = T>, D: Get<T>> Shr<usize> for TypeWithDefault<T, D> {
152 type Output = Self;
153 fn shr(self, rhs: usize) -> Self {
154 Self::new(self.0 >> rhs)
155 }
156}
157
158impl<T: Shl<u32, Output = T>, D: Get<T>> Shl<u32> for TypeWithDefault<T, D> {
159 type Output = Self;
160 fn shl(self, rhs: u32) -> Self {
161 Self::new(self.0 << rhs)
162 }
163}
164
165impl<T: Shl<usize, Output = T>, D: Get<T>> Shl<usize> for TypeWithDefault<T, D> {
166 type Output = Self;
167 fn shl(self, rhs: usize) -> Self {
168 Self::new(self.0 << rhs)
169 }
170}
171
172impl<T: RemAssign, D: Get<T>> RemAssign for TypeWithDefault<T, D> {
173 fn rem_assign(&mut self, rhs: Self) {
174 self.0 %= rhs.0
175 }
176}
177
178impl<T: DivAssign, D: Get<T>> DivAssign for TypeWithDefault<T, D> {
179 fn div_assign(&mut self, rhs: Self) {
180 self.0 /= rhs.0
181 }
182}
183
184impl<T: MulAssign, D: Get<T>> MulAssign for TypeWithDefault<T, D> {
185 fn mul_assign(&mut self, rhs: Self) {
186 self.0 *= rhs.0
187 }
188}
189
190impl<T: SubAssign, D: Get<T>> SubAssign for TypeWithDefault<T, D> {
191 fn sub_assign(&mut self, rhs: Self) {
192 self.0 -= rhs.0
193 }
194}
195
196impl<T: AddAssign, D: Get<T>> AddAssign for TypeWithDefault<T, D> {
197 fn add_assign(&mut self, rhs: Self) {
198 self.0 += rhs.0
199 }
200}
201
202impl<T: Display, D: Get<T>> Display for TypeWithDefault<T, D> {
203 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
204 write!(f, "{}", self.0)
205 }
206}
207
208macro_rules! impl_from {
209 ($for_type:ty $(, $from_type:ty)*) => {
210 $(
211 impl<D: Get<$for_type>> From<$from_type> for TypeWithDefault<$for_type, D> {
212 fn from(value: $from_type) -> Self {
213 Self::new(value.into())
214 }
215 }
216 )*
217 }
218}
219impl_from!(u128, u128, u64, u32, u16, u8);
220impl_from!(u64, u64, u32, u16, u8);
221impl_from!(u32, u32, u16, u8);
222impl_from!(u16, u16, u8);
223impl_from!(u8, u8);
224
225macro_rules! impl_try_from {
226 ($for_type:ty $(, $try_from_type:ty)*) => {
227 $(
228 impl<D: Get<$for_type>> TryFrom<$try_from_type> for TypeWithDefault<$for_type, D> {
229 type Error = <$for_type as TryFrom<$try_from_type>>::Error;
230 fn try_from(n: $try_from_type) -> Result<TypeWithDefault<$for_type, D>, Self::Error> {
231 <$for_type as TryFrom<$try_from_type>>::try_from(n).map(Self::new)
232 }
233 }
234 )*
235 }
236}
237impl_try_from!(u8, u16, u32, u64, u128);
238impl_try_from!(u16, u32, u64, u128);
239impl_try_from!(u32, u64, u128);
240impl_try_from!(u64, u128);
241
242impl<T: TryFrom<usize>, D: Get<T>> TryFrom<usize> for TypeWithDefault<T, D> {
243 type Error = <T as TryFrom<usize>>::Error;
244 fn try_from(n: usize) -> Result<TypeWithDefault<T, D>, Self::Error> {
245 T::try_from(n).map(Self::new)
246 }
247}
248
249impl<T: TryInto<u8>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u8 {
250 type Error = <T as TryInto<u8>>::Error;
251 fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
252 value.0.try_into()
253 }
254}
255
256impl<T: TryInto<u16>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u16 {
257 type Error = <T as TryInto<u16>>::Error;
258 fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
259 value.0.try_into()
260 }
261}
262
263impl<T: TryInto<u32>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u32 {
264 type Error = <T as TryInto<u32>>::Error;
265 fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
266 value.0.try_into()
267 }
268}
269
270impl<T: TryInto<u64>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u64 {
271 type Error = <T as TryInto<u64>>::Error;
272 fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
273 value.0.try_into()
274 }
275}
276
277impl<T: TryInto<u128>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u128 {
278 type Error = <T as TryInto<u128>>::Error;
279 fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
280 value.0.try_into()
281 }
282}
283
284impl<T: TryInto<usize>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for usize {
285 type Error = <T as TryInto<usize>>::Error;
286 fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
287 value.0.try_into()
288 }
289}
290
291impl<T: Zero + PartialEq, D: Get<T>> Zero for TypeWithDefault<T, D> {
292 fn zero() -> Self {
293 Self::new(T::zero())
294 }
295
296 fn is_zero(&self) -> bool {
297 self.0 == T::zero()
298 }
299}
300
301impl<T: Bounded, D: Get<T>> Bounded for TypeWithDefault<T, D> {
302 fn min_value() -> Self {
303 Self::new(T::min_value())
304 }
305
306 fn max_value() -> Self {
307 Self::new(T::max_value())
308 }
309}
310
311impl<T: PrimInt, D: Get<T>> PrimInt for TypeWithDefault<T, D> {
312 fn count_ones(self) -> u32 {
313 self.0.count_ones()
314 }
315
316 fn leading_zeros(self) -> u32 {
317 self.0.leading_zeros()
318 }
319
320 fn trailing_zeros(self) -> u32 {
321 self.0.trailing_zeros()
322 }
323
324 fn rotate_left(self, n: u32) -> Self {
325 Self::new(self.0.rotate_left(n))
326 }
327
328 fn rotate_right(self, n: u32) -> Self {
329 Self::new(self.0.rotate_right(n))
330 }
331
332 fn swap_bytes(self) -> Self {
333 Self::new(self.0.swap_bytes())
334 }
335
336 fn from_be(x: Self) -> Self {
337 Self::new(T::from_be(x.0))
338 }
339
340 fn from_le(x: Self) -> Self {
341 Self::new(T::from_le(x.0))
342 }
343
344 fn to_be(self) -> Self {
345 Self::new(self.0.to_be())
346 }
347
348 fn to_le(self) -> Self {
349 Self::new(self.0.to_le())
350 }
351
352 fn count_zeros(self) -> u32 {
353 self.0.count_zeros()
354 }
355
356 fn signed_shl(self, n: u32) -> Self {
357 Self::new(self.0.signed_shl(n))
358 }
359
360 fn signed_shr(self, n: u32) -> Self {
361 Self::new(self.0.signed_shr(n))
362 }
363
364 fn unsigned_shl(self, n: u32) -> Self {
365 Self::new(self.0.unsigned_shl(n))
366 }
367
368 fn unsigned_shr(self, n: u32) -> Self {
369 Self::new(self.0.unsigned_shr(n))
370 }
371
372 fn pow(self, exp: u32) -> Self {
373 Self::new(self.0.pow(exp))
374 }
375}
376
377impl<T: Saturating, D: Get<T>> Saturating for TypeWithDefault<T, D> {
378 fn saturating_add(self, rhs: Self) -> Self {
379 Self::new(self.0.saturating_add(rhs.0))
380 }
381
382 fn saturating_sub(self, rhs: Self) -> Self {
383 Self::new(self.0.saturating_sub(rhs.0))
384 }
385}
386
387impl<T: Div<Output = T>, D: Get<T>> Div for TypeWithDefault<T, D> {
388 type Output = Self;
389 fn div(self, rhs: Self) -> Self {
390 Self::new(self.0 / rhs.0)
391 }
392}
393
394impl<T: Mul<Output = T>, D: Get<T>> Mul for TypeWithDefault<T, D> {
395 type Output = Self;
396 fn mul(self, rhs: Self) -> Self {
397 Self::new(self.0 * rhs.0)
398 }
399}
400
401impl<T: CheckedDiv, D: Get<T>> CheckedDiv for TypeWithDefault<T, D> {
402 fn checked_div(&self, rhs: &Self) -> Option<Self> {
403 self.0.checked_div(&rhs.0).map(Self::new)
404 }
405}
406
407impl<T: CheckedMul, D: Get<T>> CheckedMul for TypeWithDefault<T, D> {
408 fn checked_mul(&self, rhs: &Self) -> Option<Self> {
409 self.0.checked_mul(&rhs.0).map(Self::new)
410 }
411}
412
413impl<T: Sub<Output = T>, D: Get<T>> Sub for TypeWithDefault<T, D> {
414 type Output = Self;
415 fn sub(self, rhs: Self) -> Self {
416 Self::new(self.0 - rhs.0)
417 }
418}
419
420impl<T: CheckedSub, D: Get<T>> CheckedSub for TypeWithDefault<T, D> {
421 fn checked_sub(&self, rhs: &Self) -> Option<Self> {
422 self.0.checked_sub(&rhs.0).map(Self::new)
423 }
424}
425
426impl<T: Add<Output = T>, D: Get<T>> Add for TypeWithDefault<T, D> {
427 type Output = Self;
428 fn add(self, rhs: Self) -> Self {
429 Self::new(self.0 + rhs.0)
430 }
431}
432
433impl<T: CheckedAdd, D: Get<T>> CheckedAdd for TypeWithDefault<T, D> {
434 fn checked_add(&self, rhs: &Self) -> Option<Self> {
435 self.0.checked_add(&rhs.0).map(Self::new)
436 }
437}
438
439impl<T: BitAnd<Output = T>, D: Get<T>> BitAnd for TypeWithDefault<T, D> {
440 type Output = Self;
441 fn bitand(self, rhs: Self) -> Self {
442 Self::new(self.0 & rhs.0)
443 }
444}
445
446impl<T: BitOr<Output = T>, D: Get<T>> BitOr for TypeWithDefault<T, D> {
447 type Output = Self;
448 fn bitor(self, rhs: Self) -> Self {
449 Self::new(self.0 | rhs.0)
450 }
451}
452
453impl<T: BitXor<Output = T>, D: Get<T>> BitXor for TypeWithDefault<T, D> {
454 type Output = Self;
455 fn bitxor(self, rhs: Self) -> Self {
456 Self::new(self.0 ^ rhs.0)
457 }
458}
459
460impl<T: One, D: Get<T>> One for TypeWithDefault<T, D> {
461 fn one() -> Self {
462 Self::new(T::one())
463 }
464}
465
466impl<T: Not<Output = T>, D: Get<T>> Not for TypeWithDefault<T, D> {
467 type Output = Self;
468 fn not(self) -> Self {
469 Self::new(self.0.not())
470 }
471}
472
473impl<T: NumCast, D: Get<T>> NumCast for TypeWithDefault<T, D> {
474 fn from<P: ToPrimitive>(n: P) -> Option<Self> {
475 <T as NumCast>::from(n).map_or(None, |n| Some(Self::new(n)))
476 }
477}
478
479impl<T: Num, D: Get<T>> Num for TypeWithDefault<T, D> {
480 type FromStrRadixErr = <T as Num>::FromStrRadixErr;
481
482 fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
483 T::from_str_radix(s, radix).map(Self::new)
484 }
485}
486
487impl<T: ToPrimitive, D: Get<T>> ToPrimitive for TypeWithDefault<T, D> {
488 fn to_i64(&self) -> Option<i64> {
489 self.0.to_i64()
490 }
491
492 fn to_u64(&self) -> Option<u64> {
493 self.0.to_u64()
494 }
495
496 fn to_i128(&self) -> Option<i128> {
497 self.0.to_i128()
498 }
499
500 fn to_u128(&self) -> Option<u128> {
501 self.0.to_u128()
502 }
503}
504
505impl<T, D: Get<T>> From<Compact<TypeWithDefault<T, D>>> for TypeWithDefault<T, D> {
506 fn from(c: Compact<TypeWithDefault<T, D>>) -> Self {
507 c.0
508 }
509}
510
511impl<T: HasCompact, D: Get<T>> CompactAs for TypeWithDefault<T, D> {
512 type As = T;
513
514 fn encode_as(&self) -> &Self::As {
515 &self.0
516 }
517
518 fn decode_from(val: Self::As) -> Result<Self, codec::Error> {
519 Ok(Self::new(val))
520 }
521}
522
523#[cfg(test)]
524mod tests {
525 use super::TypeWithDefault;
526 use scale_info::TypeInfo;
527 use sp_arithmetic::traits::{AtLeast16Bit, AtLeast32Bit, AtLeast8Bit};
528 use sp_core::Get;
529
530 #[test]
531 #[allow(dead_code)]
532 fn test_type_with_default_impl_base_arithmetic() {
533 trait WrapAtLeast8Bit: AtLeast8Bit {}
534 trait WrapAtLeast16Bit: AtLeast16Bit {}
535 trait WrapAtLeast32Bit: AtLeast32Bit {}
536
537 struct Getu8;
538 impl Get<u8> for Getu8 {
539 fn get() -> u8 {
540 0
541 }
542 }
543 type U8WithDefault = TypeWithDefault<u8, Getu8>;
544 impl WrapAtLeast8Bit for U8WithDefault {}
545
546 struct Getu16;
547 impl Get<u16> for Getu16 {
548 fn get() -> u16 {
549 0
550 }
551 }
552 type U16WithDefault = TypeWithDefault<u16, Getu16>;
553 impl WrapAtLeast16Bit for U16WithDefault {}
554
555 struct Getu32;
556 impl Get<u32> for Getu32 {
557 fn get() -> u32 {
558 0
559 }
560 }
561 type U32WithDefault = TypeWithDefault<u32, Getu32>;
562 impl WrapAtLeast32Bit for U32WithDefault {}
563
564 struct Getu64;
565 impl Get<u64> for Getu64 {
566 fn get() -> u64 {
567 0
568 }
569 }
570 type U64WithDefault = TypeWithDefault<u64, Getu64>;
571 impl WrapAtLeast32Bit for U64WithDefault {}
572
573 struct Getu128;
574 impl Get<u128> for Getu128 {
575 fn get() -> u128 {
576 0
577 }
578 }
579 type U128WithDefault = TypeWithDefault<u128, Getu128>;
580 impl WrapAtLeast32Bit for U128WithDefault {}
581
582 assert_eq!(U8WithDefault::type_info(), <u8 as TypeInfo>::type_info());
583 assert_eq!(U16WithDefault::type_info(), <u16 as TypeInfo>::type_info());
584 assert_eq!(U32WithDefault::type_info(), <u32 as TypeInfo>::type_info());
585 assert_eq!(U64WithDefault::type_info(), <u64 as TypeInfo>::type_info());
586 assert_eq!(U128WithDefault::type_info(), <u128 as TypeInfo>::type_info());
587 }
588}