sp_runtime/
type_with_default.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Provides a type that wraps another type and provides a default value.
19
20use crate::traits::{Bounded, One, Zero};
21use codec::{Compact, CompactAs, Decode, 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/// A type that wraps another type and provides a default value.
41///
42/// Passes through arithmetical and many other operations to the inner value.
43/// Type information for metadata is the same as the inner value's type.
44#[derive(Encode, Decode, 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
54// Hides implementation details from the outside (for metadata type information).
55//
56// The type info showed in metadata is the one of the inner value's type.
57impl<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: From<u16>, D: Get<T>> From<u16> for TypeWithDefault<T, D> {
107	fn from(value: u16) -> Self {
108		Self::new(value.into())
109	}
110}
111
112impl<T: From<u32>, D: Get<T>> From<u32> for TypeWithDefault<T, D> {
113	fn from(value: u32) -> Self {
114		Self::new(value.into())
115	}
116}
117
118impl<T: From<u64>, D: Get<T>> From<u64> for TypeWithDefault<T, D> {
119	fn from(value: u64) -> Self {
120		Self::new(value.into())
121	}
122}
123
124impl<T: CheckedNeg, D: Get<T>> CheckedNeg for TypeWithDefault<T, D> {
125	fn checked_neg(&self) -> Option<Self> {
126		self.0.checked_neg().map(Self::new)
127	}
128}
129
130impl<T: CheckedRem, D: Get<T>> CheckedRem for TypeWithDefault<T, D> {
131	fn checked_rem(&self, rhs: &Self) -> Option<Self> {
132		self.0.checked_rem(&rhs.0).map(Self::new)
133	}
134}
135
136impl<T: CheckedShr, D: Get<T>> CheckedShr for TypeWithDefault<T, D> {
137	fn checked_shr(&self, n: u32) -> Option<Self> {
138		self.0.checked_shr(n).map(Self::new)
139	}
140}
141
142impl<T: CheckedShl, D: Get<T>> CheckedShl for TypeWithDefault<T, D> {
143	fn checked_shl(&self, n: u32) -> Option<Self> {
144		self.0.checked_shl(n).map(Self::new)
145	}
146}
147
148impl<T: Rem<Output = T>, D: Get<T>> Rem for TypeWithDefault<T, D> {
149	type Output = Self;
150	fn rem(self, rhs: Self) -> Self {
151		Self::new(self.0 % rhs.0)
152	}
153}
154
155impl<T: Rem<u32, Output = T>, D: Get<T>> Rem<u32> for TypeWithDefault<T, D> {
156	type Output = Self;
157	fn rem(self, rhs: u32) -> Self {
158		Self::new(self.0 % (rhs.into()))
159	}
160}
161
162impl<T: Shr<u32, Output = T>, D: Get<T>> Shr<u32> for TypeWithDefault<T, D> {
163	type Output = Self;
164	fn shr(self, rhs: u32) -> Self {
165		Self::new(self.0 >> rhs)
166	}
167}
168
169impl<T: Shr<usize, Output = T>, D: Get<T>> Shr<usize> for TypeWithDefault<T, D> {
170	type Output = Self;
171	fn shr(self, rhs: usize) -> Self {
172		Self::new(self.0 >> rhs)
173	}
174}
175
176impl<T: Shl<u32, Output = T>, D: Get<T>> Shl<u32> for TypeWithDefault<T, D> {
177	type Output = Self;
178	fn shl(self, rhs: u32) -> Self {
179		Self::new(self.0 << rhs)
180	}
181}
182
183impl<T: Shl<usize, Output = T>, D: Get<T>> Shl<usize> for TypeWithDefault<T, D> {
184	type Output = Self;
185	fn shl(self, rhs: usize) -> Self {
186		Self::new(self.0 << rhs)
187	}
188}
189
190impl<T: RemAssign, D: Get<T>> RemAssign for TypeWithDefault<T, D> {
191	fn rem_assign(&mut self, rhs: Self) {
192		self.0 %= rhs.0
193	}
194}
195
196impl<T: DivAssign, D: Get<T>> DivAssign for TypeWithDefault<T, D> {
197	fn div_assign(&mut self, rhs: Self) {
198		self.0 /= rhs.0
199	}
200}
201
202impl<T: MulAssign, D: Get<T>> MulAssign for TypeWithDefault<T, D> {
203	fn mul_assign(&mut self, rhs: Self) {
204		self.0 *= rhs.0
205	}
206}
207
208impl<T: SubAssign, D: Get<T>> SubAssign for TypeWithDefault<T, D> {
209	fn sub_assign(&mut self, rhs: Self) {
210		self.0 -= rhs.0
211	}
212}
213
214impl<T: AddAssign, D: Get<T>> AddAssign for TypeWithDefault<T, D> {
215	fn add_assign(&mut self, rhs: Self) {
216		self.0 += rhs.0
217	}
218}
219
220impl<T: From<u8>, D: Get<T>> From<u8> for TypeWithDefault<T, D> {
221	fn from(value: u8) -> Self {
222		Self::new(value.into())
223	}
224}
225
226impl<T: Display, D: Get<T>> Display for TypeWithDefault<T, D> {
227	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
228		write!(f, "{}", self.0)
229	}
230}
231
232impl<T: TryFrom<u128>, D: Get<T>> TryFrom<u128> for TypeWithDefault<T, D> {
233	type Error = <T as TryFrom<u128>>::Error;
234	fn try_from(n: u128) -> Result<TypeWithDefault<T, D>, Self::Error> {
235		T::try_from(n).map(Self::new)
236	}
237}
238
239impl<T: TryFrom<usize>, D: Get<T>> TryFrom<usize> for TypeWithDefault<T, D> {
240	type Error = <T as TryFrom<usize>>::Error;
241	fn try_from(n: usize) -> Result<TypeWithDefault<T, D>, Self::Error> {
242		T::try_from(n).map(Self::new)
243	}
244}
245
246impl<T: TryInto<u8>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u8 {
247	type Error = <T as TryInto<u8>>::Error;
248	fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
249		value.0.try_into()
250	}
251}
252
253impl<T: TryInto<u16>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u16 {
254	type Error = <T as TryInto<u16>>::Error;
255	fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
256		value.0.try_into()
257	}
258}
259
260impl<T: TryInto<u32>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u32 {
261	type Error = <T as TryInto<u32>>::Error;
262	fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
263		value.0.try_into()
264	}
265}
266
267impl<T: TryInto<u64>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u64 {
268	type Error = <T as TryInto<u64>>::Error;
269	fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
270		value.0.try_into()
271	}
272}
273
274impl<T: TryInto<u128>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for u128 {
275	type Error = <T as TryInto<u128>>::Error;
276	fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
277		value.0.try_into()
278	}
279}
280
281impl<T: TryInto<usize>, D: Get<T>> TryFrom<TypeWithDefault<T, D>> for usize {
282	type Error = <T as TryInto<usize>>::Error;
283	fn try_from(value: TypeWithDefault<T, D>) -> Result<Self, Self::Error> {
284		value.0.try_into()
285	}
286}
287
288impl<T: Zero + PartialEq, D: Get<T>> Zero for TypeWithDefault<T, D> {
289	fn zero() -> Self {
290		Self::new(T::zero())
291	}
292
293	fn is_zero(&self) -> bool {
294		self.0 == T::zero()
295	}
296}
297
298impl<T: Bounded, D: Get<T>> Bounded for TypeWithDefault<T, D> {
299	fn min_value() -> Self {
300		Self::new(T::min_value())
301	}
302
303	fn max_value() -> Self {
304		Self::new(T::max_value())
305	}
306}
307
308impl<T: PrimInt, D: Get<T>> PrimInt for TypeWithDefault<T, D> {
309	fn count_ones(self) -> u32 {
310		self.0.count_ones()
311	}
312
313	fn leading_zeros(self) -> u32 {
314		self.0.leading_zeros()
315	}
316
317	fn trailing_zeros(self) -> u32 {
318		self.0.trailing_zeros()
319	}
320
321	fn rotate_left(self, n: u32) -> Self {
322		Self::new(self.0.rotate_left(n))
323	}
324
325	fn rotate_right(self, n: u32) -> Self {
326		Self::new(self.0.rotate_right(n))
327	}
328
329	fn swap_bytes(self) -> Self {
330		Self::new(self.0.swap_bytes())
331	}
332
333	fn from_be(x: Self) -> Self {
334		Self::new(T::from_be(x.0))
335	}
336
337	fn from_le(x: Self) -> Self {
338		Self::new(T::from_le(x.0))
339	}
340
341	fn to_be(self) -> Self {
342		Self::new(self.0.to_be())
343	}
344
345	fn to_le(self) -> Self {
346		Self::new(self.0.to_le())
347	}
348
349	fn count_zeros(self) -> u32 {
350		self.0.count_zeros()
351	}
352
353	fn signed_shl(self, n: u32) -> Self {
354		Self::new(self.0.signed_shl(n))
355	}
356
357	fn signed_shr(self, n: u32) -> Self {
358		Self::new(self.0.signed_shr(n))
359	}
360
361	fn unsigned_shl(self, n: u32) -> Self {
362		Self::new(self.0.unsigned_shl(n))
363	}
364
365	fn unsigned_shr(self, n: u32) -> Self {
366		Self::new(self.0.unsigned_shr(n))
367	}
368
369	fn pow(self, exp: u32) -> Self {
370		Self::new(self.0.pow(exp))
371	}
372}
373
374impl<T: Saturating, D: Get<T>> Saturating for TypeWithDefault<T, D> {
375	fn saturating_add(self, rhs: Self) -> Self {
376		Self::new(self.0.saturating_add(rhs.0))
377	}
378
379	fn saturating_sub(self, rhs: Self) -> Self {
380		Self::new(self.0.saturating_sub(rhs.0))
381	}
382}
383
384impl<T: Div<Output = T>, D: Get<T>> Div for TypeWithDefault<T, D> {
385	type Output = Self;
386	fn div(self, rhs: Self) -> Self {
387		Self::new(self.0 / rhs.0)
388	}
389}
390
391impl<T: Mul<Output = T>, D: Get<T>> Mul for TypeWithDefault<T, D> {
392	type Output = Self;
393	fn mul(self, rhs: Self) -> Self {
394		Self::new(self.0 * rhs.0)
395	}
396}
397
398impl<T: CheckedDiv, D: Get<T>> CheckedDiv for TypeWithDefault<T, D> {
399	fn checked_div(&self, rhs: &Self) -> Option<Self> {
400		self.0.checked_div(&rhs.0).map(Self::new)
401	}
402}
403
404impl<T: CheckedMul, D: Get<T>> CheckedMul for TypeWithDefault<T, D> {
405	fn checked_mul(&self, rhs: &Self) -> Option<Self> {
406		self.0.checked_mul(&rhs.0).map(Self::new)
407	}
408}
409
410impl<T: Sub<Output = T>, D: Get<T>> Sub for TypeWithDefault<T, D> {
411	type Output = Self;
412	fn sub(self, rhs: Self) -> Self {
413		Self::new(self.0 - rhs.0)
414	}
415}
416
417impl<T: CheckedSub, D: Get<T>> CheckedSub for TypeWithDefault<T, D> {
418	fn checked_sub(&self, rhs: &Self) -> Option<Self> {
419		self.0.checked_sub(&rhs.0).map(Self::new)
420	}
421}
422
423impl<T: Add<Output = T>, D: Get<T>> Add for TypeWithDefault<T, D> {
424	type Output = Self;
425	fn add(self, rhs: Self) -> Self {
426		Self::new(self.0 + rhs.0)
427	}
428}
429
430impl<T: CheckedAdd, D: Get<T>> CheckedAdd for TypeWithDefault<T, D> {
431	fn checked_add(&self, rhs: &Self) -> Option<Self> {
432		self.0.checked_add(&rhs.0).map(Self::new)
433	}
434}
435
436impl<T: BitAnd<Output = T>, D: Get<T>> BitAnd for TypeWithDefault<T, D> {
437	type Output = Self;
438	fn bitand(self, rhs: Self) -> Self {
439		Self::new(self.0 & rhs.0)
440	}
441}
442
443impl<T: BitOr<Output = T>, D: Get<T>> BitOr for TypeWithDefault<T, D> {
444	type Output = Self;
445	fn bitor(self, rhs: Self) -> Self {
446		Self::new(self.0 | rhs.0)
447	}
448}
449
450impl<T: BitXor<Output = T>, D: Get<T>> BitXor for TypeWithDefault<T, D> {
451	type Output = Self;
452	fn bitxor(self, rhs: Self) -> Self {
453		Self::new(self.0 ^ rhs.0)
454	}
455}
456
457impl<T: One, D: Get<T>> One for TypeWithDefault<T, D> {
458	fn one() -> Self {
459		Self::new(T::one())
460	}
461}
462
463impl<T: Not<Output = T>, D: Get<T>> Not for TypeWithDefault<T, D> {
464	type Output = Self;
465	fn not(self) -> Self {
466		Self::new(self.0.not())
467	}
468}
469
470impl<T: NumCast, D: Get<T>> NumCast for TypeWithDefault<T, D> {
471	fn from<P: ToPrimitive>(n: P) -> Option<Self> {
472		<T as NumCast>::from(n).map_or(None, |n| Some(Self::new(n)))
473	}
474}
475
476impl<T: Num, D: Get<T>> Num for TypeWithDefault<T, D> {
477	type FromStrRadixErr = <T as Num>::FromStrRadixErr;
478
479	fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
480		T::from_str_radix(s, radix).map(Self::new)
481	}
482}
483
484impl<T: ToPrimitive, D: Get<T>> ToPrimitive for TypeWithDefault<T, D> {
485	fn to_i64(&self) -> Option<i64> {
486		self.0.to_i64()
487	}
488
489	fn to_u64(&self) -> Option<u64> {
490		self.0.to_u64()
491	}
492
493	fn to_i128(&self) -> Option<i128> {
494		self.0.to_i128()
495	}
496
497	fn to_u128(&self) -> Option<u128> {
498		self.0.to_u128()
499	}
500}
501
502impl<T, D: Get<T>> From<Compact<TypeWithDefault<T, D>>> for TypeWithDefault<T, D> {
503	fn from(c: Compact<TypeWithDefault<T, D>>) -> Self {
504		c.0
505	}
506}
507
508impl<T: HasCompact, D: Get<T>> CompactAs for TypeWithDefault<T, D> {
509	type As = T;
510
511	fn encode_as(&self) -> &Self::As {
512		&self.0
513	}
514
515	fn decode_from(val: Self::As) -> Result<Self, codec::Error> {
516		Ok(Self::new(val))
517	}
518}