Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more types in TypeWithDefault #6411

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions prdoc/pr_6411.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
title: "Support more types in TypeWithDefault"

doc:
- audience: Runtime Dev
description: |
This PR supports more integer types to be used with `TypeWithDefault` and makes `TypeWithDefault<u8/u16/u32, ..>: BaseArithmetic` satisfied

crates:
- name: sp-runtime
bump: patch
123 changes: 93 additions & 30 deletions substrate/primitives/runtime/src/type_with_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,6 @@ impl<T, D: Get<T>> Default for TypeWithDefault<T, D> {
}
}

impl<T: From<u16>, D: Get<T>> From<u16> for TypeWithDefault<T, D> {
fn from(value: u16) -> Self {
Self::new(value.into())
}
}

impl<T: From<u32>, D: Get<T>> From<u32> for TypeWithDefault<T, D> {
fn from(value: u32) -> Self {
Self::new(value.into())
}
}

impl<T: From<u64>, D: Get<T>> From<u64> for TypeWithDefault<T, D> {
fn from(value: u64) -> Self {
Self::new(value.into())
}
}

impl<T: CheckedNeg, D: Get<T>> CheckedNeg for TypeWithDefault<T, D> {
fn checked_neg(&self) -> Option<Self> {
self.0.checked_neg().map(Self::new)
Expand Down Expand Up @@ -205,24 +187,45 @@ impl<T: AddAssign, D: Get<T>> AddAssign for TypeWithDefault<T, D> {
}
}

impl<T: From<u8>, D: Get<T>> From<u8> for TypeWithDefault<T, D> {
fn from(value: u8) -> Self {
Self::new(value.into())
}
}

impl<T: Display, D: Get<T>> Display for TypeWithDefault<T, D> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}

impl<T: TryFrom<u128>, D: Get<T>> TryFrom<u128> for TypeWithDefault<T, D> {
type Error = <T as TryFrom<u128>>::Error;
fn try_from(n: u128) -> Result<TypeWithDefault<T, D>, Self::Error> {
T::try_from(n).map(Self::new)
}
}
macro_rules! impl_from {
($for_type:ty $(, $from_type:ty)*) => {
$(
impl<D: Get<$for_type>> From<$from_type> for TypeWithDefault<$for_type, D> {
fn from(value: $from_type) -> Self {
Self::new(value.into())
}
}
)*
}
}
impl_from!(u128, u128, u64, u32, u16, u8);
impl_from!(u64, u64, u32, u16, u8);
impl_from!(u32, u32, u16, u8);
impl_from!(u16, u16, u8);
impl_from!(u8, u8);

macro_rules! impl_try_from {
($for_type:ty $(, $try_from_type:ty)*) => {
$(
impl<D: Get<$for_type>> TryFrom<$try_from_type> for TypeWithDefault<$for_type, D> {
type Error = <$for_type as TryFrom<$try_from_type>>::Error;
fn try_from(n: $try_from_type) -> Result<TypeWithDefault<$for_type, D>, Self::Error> {
<$for_type as TryFrom<$try_from_type>>::try_from(n).map(Self::new)
}
}
)*
}
}
impl_try_from!(u8, u16, u32, u64, u128);
impl_try_from!(u16, u32, u64, u128);
impl_try_from!(u32, u64, u128);
impl_try_from!(u64, u128);

impl<T: TryFrom<usize>, D: Get<T>> TryFrom<usize> for TypeWithDefault<T, D> {
type Error = <T as TryFrom<usize>>::Error;
Expand Down Expand Up @@ -504,3 +507,63 @@ impl<T: HasCompact, D: Get<T>> CompactAs for TypeWithDefault<T, D> {
Ok(Self::new(val))
}
}

#[cfg(test)]
mod tests {
use super::TypeWithDefault;
use sp_arithmetic::traits::{AtLeast16Bit, AtLeast32Bit, AtLeast8Bit};
use sp_core::Get;

#[test]
#[allow(dead_code)]
fn test_type_with_default_impl_base_arithmetic() {
bkchr marked this conversation as resolved.
Show resolved Hide resolved
trait WrapAtLeast8Bit: AtLeast8Bit {}
trait WrapAtLeast16Bit: AtLeast16Bit {}
trait WrapAtLeast32Bit: AtLeast32Bit {}

struct Getu8;
impl Get<u8> for Getu8 {
fn get() -> u8 {
0
}
}
type U8WithDefault = TypeWithDefault<u8, Getu8>;
impl WrapAtLeast8Bit for U8WithDefault {}

struct Getu16;
impl Get<u16> for Getu16 {
fn get() -> u16 {
0
}
}
type U16WithDefault = TypeWithDefault<u16, Getu16>;
impl WrapAtLeast16Bit for U16WithDefault {}

struct Getu32;
impl Get<u32> for Getu32 {
fn get() -> u32 {
0
}
}
type U32WithDefault = TypeWithDefault<u32, Getu32>;
impl WrapAtLeast32Bit for U32WithDefault {}

struct Getu64;
impl Get<u64> for Getu64 {
fn get() -> u64 {
0
}
}
type U64WithDefault = TypeWithDefault<u64, Getu64>;
impl WrapAtLeast32Bit for U64WithDefault {}

struct Getu128;
impl Get<u128> for Getu128 {
fn get() -> u128 {
0
}
}
type U128WithDefault = TypeWithDefault<u128, Getu128>;
impl WrapAtLeast32Bit for U128WithDefault {}
}
}
Loading