mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 04:41:02 +00:00
Move Get and bounded types to sp-core (#12203)
* Move Get and bounded types to sp-core * Fixes * cargo fmt * Fixes
This commit is contained in:
+2
-2
@@ -17,7 +17,7 @@
|
||||
|
||||
//! Traits, types and structs to support a bounded BTreeMap.
|
||||
|
||||
use crate::traits::{Get, TryCollect};
|
||||
use crate::{Get, TryCollect};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use sp_std::{borrow::Borrow, collections::btree_map::BTreeMap, marker::PhantomData, ops::Deref};
|
||||
|
||||
@@ -363,7 +363,7 @@ where
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
use crate::traits::ConstU32;
|
||||
use crate::ConstU32;
|
||||
|
||||
fn map_from_keys<K>(keys: &[K]) -> BTreeMap<K, ()>
|
||||
where
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
|
||||
//! Traits, types and structs to support a bounded `BTreeSet`.
|
||||
|
||||
use crate::traits::{Get, TryCollect};
|
||||
use crate::{Get, TryCollect};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use sp_std::{borrow::Borrow, collections::btree_set::BTreeSet, marker::PhantomData, ops::Deref};
|
||||
|
||||
@@ -321,7 +321,7 @@ where
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
use crate::traits::ConstU32;
|
||||
use crate::ConstU32;
|
||||
|
||||
fn set_from_keys<T>(keys: &[T]) -> BTreeSet<T>
|
||||
where
|
||||
+2
-2
@@ -19,7 +19,7 @@
|
||||
//! or a double map.
|
||||
|
||||
use super::WeakBoundedVec;
|
||||
use crate::traits::{Get, TryCollect};
|
||||
use crate::{Get, TryCollect};
|
||||
use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};
|
||||
use core::{
|
||||
ops::{Deref, Index, IndexMut, RangeBounds},
|
||||
@@ -884,7 +884,7 @@ where
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
use crate::{bounded_vec, traits::ConstU32};
|
||||
use crate::{bounded_vec, ConstU32};
|
||||
|
||||
#[test]
|
||||
fn slide_works() {
|
||||
+2
-2
@@ -19,7 +19,7 @@
|
||||
//! or a double map.
|
||||
|
||||
use super::{BoundedSlice, BoundedVec};
|
||||
use crate::traits::Get;
|
||||
use crate::Get;
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use core::{
|
||||
ops::{Deref, Index, IndexMut},
|
||||
@@ -453,7 +453,7 @@ where
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
use crate::traits::ConstU32;
|
||||
use crate::ConstU32;
|
||||
|
||||
#[test]
|
||||
fn bound_returns_correct_value() {
|
||||
@@ -53,6 +53,7 @@ pub mod hashing;
|
||||
|
||||
#[cfg(feature = "full_crypto")]
|
||||
pub use hashing::{blake2_128, blake2_256, keccak_256, twox_128, twox_256, twox_64};
|
||||
pub mod bounded;
|
||||
pub mod crypto;
|
||||
pub mod hexdisplay;
|
||||
|
||||
@@ -466,3 +467,239 @@ macro_rules! impl_maybe_marker {
|
||||
// The maximum possible allocation size was chosen rather arbitrary, 32 MiB should be enough for
|
||||
// everybody.
|
||||
pub const MAX_POSSIBLE_ALLOCATION: u32 = 33554432; // 2^25 bytes, 32 MiB
|
||||
|
||||
/// A trait for querying a single value from a type defined in the trait.
|
||||
///
|
||||
/// It is not required that the value is constant.
|
||||
pub trait TypedGet {
|
||||
/// The type which is returned.
|
||||
type Type;
|
||||
/// Return the current value.
|
||||
fn get() -> Self::Type;
|
||||
}
|
||||
|
||||
/// A trait for querying a single value from a type.
|
||||
///
|
||||
/// It is not required that the value is constant.
|
||||
pub trait Get<T> {
|
||||
/// Return the current value.
|
||||
fn get() -> T;
|
||||
}
|
||||
|
||||
impl<T: Default> Get<T> for () {
|
||||
fn get() -> T {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement Get by returning Default for any type that implements Default.
|
||||
pub struct GetDefault;
|
||||
impl<T: Default> Get<T> for GetDefault {
|
||||
fn get() -> T {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_const_get {
|
||||
($name:ident, $t:ty) => {
|
||||
#[doc = "Const getter for a basic type."]
|
||||
#[derive($crate::RuntimeDebug)]
|
||||
pub struct $name<const T: $t>;
|
||||
impl<const T: $t> Get<$t> for $name<T> {
|
||||
fn get() -> $t {
|
||||
T
|
||||
}
|
||||
}
|
||||
impl<const T: $t> Get<Option<$t>> for $name<T> {
|
||||
fn get() -> Option<$t> {
|
||||
Some(T)
|
||||
}
|
||||
}
|
||||
impl<const T: $t> TypedGet for $name<T> {
|
||||
type Type = $t;
|
||||
fn get() -> $t {
|
||||
T
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_const_get!(ConstBool, bool);
|
||||
impl_const_get!(ConstU8, u8);
|
||||
impl_const_get!(ConstU16, u16);
|
||||
impl_const_get!(ConstU32, u32);
|
||||
impl_const_get!(ConstU64, u64);
|
||||
impl_const_get!(ConstU128, u128);
|
||||
impl_const_get!(ConstI8, i8);
|
||||
impl_const_get!(ConstI16, i16);
|
||||
impl_const_get!(ConstI32, i32);
|
||||
impl_const_get!(ConstI64, i64);
|
||||
impl_const_get!(ConstI128, i128);
|
||||
|
||||
/// Try and collect into a collection `C`.
|
||||
pub trait TryCollect<C> {
|
||||
/// The error type that gets returned when a collection can't be made from `self`.
|
||||
type Error;
|
||||
/// Consume self and try to collect the results into `C`.
|
||||
///
|
||||
/// This is useful in preventing the undesirable `.collect().try_into()` call chain on
|
||||
/// collections that need to be converted into a bounded type (e.g. `BoundedVec`).
|
||||
fn try_collect(self) -> Result<C, Self::Error>;
|
||||
}
|
||||
|
||||
/// Create new implementations of the [`Get`](crate::Get) trait.
|
||||
///
|
||||
/// The so-called parameter type can be created in four different ways:
|
||||
///
|
||||
/// - Using `const` to create a parameter type that provides a `const` getter. It is required that
|
||||
/// the `value` is const.
|
||||
///
|
||||
/// - Declare the parameter type without `const` to have more freedom when creating the value.
|
||||
///
|
||||
/// NOTE: A more substantial version of this macro is available in `frame_support` crate which
|
||||
/// allows mutable and persistant variants.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use sp_core::Get;
|
||||
/// # use sp_core::parameter_types;
|
||||
/// // This function cannot be used in a const context.
|
||||
/// fn non_const_expression() -> u64 { 99 }
|
||||
///
|
||||
/// const FIXED_VALUE: u64 = 10;
|
||||
/// parameter_types! {
|
||||
/// pub const Argument: u64 = 42 + FIXED_VALUE;
|
||||
/// /// Visibility of the type is optional
|
||||
/// OtherArgument: u64 = non_const_expression();
|
||||
/// }
|
||||
///
|
||||
/// trait Config {
|
||||
/// type Parameter: Get<u64>;
|
||||
/// type OtherParameter: Get<u64>;
|
||||
/// }
|
||||
///
|
||||
/// struct Runtime;
|
||||
/// impl Config for Runtime {
|
||||
/// type Parameter = Argument;
|
||||
/// type OtherParameter = OtherArgument;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Invalid example:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// # use sp_core::Get;
|
||||
/// # use sp_core::parameter_types;
|
||||
/// // This function cannot be used in a const context.
|
||||
/// fn non_const_expression() -> u64 { 99 }
|
||||
///
|
||||
/// parameter_types! {
|
||||
/// pub const Argument: u64 = non_const_expression();
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! parameter_types {
|
||||
(
|
||||
$( #[ $attr:meta ] )*
|
||||
$vis:vis const $name:ident: $type:ty = $value:expr;
|
||||
$( $rest:tt )*
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!(@IMPL_CONST $name , $type , $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
(
|
||||
$( #[ $attr:meta ] )*
|
||||
$vis:vis $name:ident: $type:ty = $value:expr;
|
||||
$( $rest:tt )*
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!(@IMPL $name, $type, $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
() => ();
|
||||
(@IMPL_CONST $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the value of this parameter type.
|
||||
pub const fn get() -> $type {
|
||||
$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from(Self::get())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::TypedGet for $name {
|
||||
type Type = $type;
|
||||
fn get() -> $type {
|
||||
Self::get()
|
||||
}
|
||||
}
|
||||
};
|
||||
(@IMPL $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the value of this parameter type.
|
||||
pub fn get() -> $type {
|
||||
$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from(Self::get())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::TypedGet for $name {
|
||||
type Type = $type;
|
||||
fn get() -> $type {
|
||||
Self::get()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Build a bounded vec from the given literals.
|
||||
///
|
||||
/// The type of the outcome must be known.
|
||||
///
|
||||
/// Will not handle any errors and just panic if the given literals cannot fit in the corresponding
|
||||
/// bounded vec type. Thus, this is only suitable for testing and non-consensus code.
|
||||
#[macro_export]
|
||||
#[cfg(feature = "std")]
|
||||
macro_rules! bounded_vec {
|
||||
($ ($values:expr),* $(,)?) => {
|
||||
{
|
||||
$crate::sp_std::vec![$($values),*].try_into().unwrap()
|
||||
}
|
||||
};
|
||||
( $value:expr ; $repetition:expr ) => {
|
||||
{
|
||||
$crate::sp_std::vec![$value ; $repetition].try_into().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a bounded btree-map from the given literals.
|
||||
///
|
||||
/// The type of the outcome must be known.
|
||||
///
|
||||
/// Will not handle any errors and just panic if the given literals cannot fit in the corresponding
|
||||
/// bounded vec type. Thus, this is only suitable for testing and non-consensus code.
|
||||
#[macro_export]
|
||||
#[cfg(feature = "std")]
|
||||
macro_rules! bounded_btree_map {
|
||||
($ ( $key:expr => $value:expr ),* $(,)?) => {
|
||||
{
|
||||
$crate::TryCollect::<$crate::bounded::BoundedBTreeMap<_, _, _>>::try_collect(
|
||||
$crate::sp_std::vec![$(($key, $value)),*].into_iter()
|
||||
).unwrap()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,7 +55,6 @@ use sp_std::prelude::*;
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
pub mod bounded;
|
||||
pub mod curve;
|
||||
pub mod generic;
|
||||
pub mod legacy;
|
||||
@@ -70,9 +69,6 @@ pub mod transaction_validity;
|
||||
|
||||
pub use crate::runtime_string::*;
|
||||
|
||||
// Re-export bounded types
|
||||
pub use bounded::{BoundedBTreeMap, BoundedBTreeSet, BoundedSlice, BoundedVec, WeakBoundedVec};
|
||||
|
||||
// Re-export Multiaddress
|
||||
pub use multiaddress::MultiAddress;
|
||||
|
||||
@@ -82,9 +78,13 @@ pub use generic::{Digest, DigestItem};
|
||||
pub use sp_application_crypto::{BoundToRuntimeAppPublic, RuntimeAppPublic};
|
||||
/// Re-export this since it's part of the API of this crate.
|
||||
pub use sp_core::{
|
||||
bounded::{BoundedBTreeMap, BoundedBTreeSet, BoundedSlice, BoundedVec, WeakBoundedVec},
|
||||
crypto::{key_types, AccountId32, CryptoType, CryptoTypeId, KeyTypeId},
|
||||
TypeId,
|
||||
};
|
||||
/// Re-export bounded_vec and bounded_btree_map macros only when std is enabled.
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_core::{bounded_btree_map, bounded_vec};
|
||||
|
||||
/// Re-export `RuntimeDebug`, to avoid dependency clutter.
|
||||
pub use sp_core::RuntimeDebug;
|
||||
@@ -834,45 +834,6 @@ macro_rules! assert_eq_error_rate {
|
||||
};
|
||||
}
|
||||
|
||||
/// Build a bounded vec from the given literals.
|
||||
///
|
||||
/// The type of the outcome must be known.
|
||||
///
|
||||
/// Will not handle any errors and just panic if the given literals cannot fit in the corresponding
|
||||
/// bounded vec type. Thus, this is only suitable for testing and non-consensus code.
|
||||
#[macro_export]
|
||||
#[cfg(feature = "std")]
|
||||
macro_rules! bounded_vec {
|
||||
($ ($values:expr),* $(,)?) => {
|
||||
{
|
||||
$crate::sp_std::vec![$($values),*].try_into().unwrap()
|
||||
}
|
||||
};
|
||||
( $value:expr ; $repetition:expr ) => {
|
||||
{
|
||||
$crate::sp_std::vec![$value ; $repetition].try_into().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a bounded btree-map from the given literals.
|
||||
///
|
||||
/// The type of the outcome must be known.
|
||||
///
|
||||
/// Will not handle any errors and just panic if the given literals cannot fit in the corresponding
|
||||
/// bounded vec type. Thus, this is only suitable for testing and non-consensus code.
|
||||
#[macro_export]
|
||||
#[cfg(feature = "std")]
|
||||
macro_rules! bounded_btree_map {
|
||||
($ ( $key:expr => $value:expr ),* $(,)?) => {
|
||||
{
|
||||
$crate::traits::TryCollect::<$crate::BoundedBTreeMap<_, _, _>>::try_collect(
|
||||
$crate::sp_std::vec![$(($key, $value)),*].into_iter()
|
||||
).unwrap()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Simple blob to hold an extrinsic without committing to its format and ensure it is serialized
|
||||
/// correctly.
|
||||
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode, TypeInfo)]
|
||||
|
||||
@@ -38,6 +38,11 @@ pub use sp_arithmetic::traits::{
|
||||
};
|
||||
use sp_core::{self, storage::StateVersion, Hasher, RuntimeDebug, TypeId};
|
||||
#[doc(hidden)]
|
||||
pub use sp_core::{
|
||||
parameter_types, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128,
|
||||
ConstU16, ConstU32, ConstU64, ConstU8, Get, GetDefault, TryCollect, TypedGet,
|
||||
};
|
||||
#[doc(hidden)]
|
||||
pub use sp_std::marker::PhantomData;
|
||||
use sp_std::{self, fmt::Debug, prelude::*};
|
||||
#[cfg(feature = "std")]
|
||||
@@ -276,203 +281,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for querying a single value from a type defined in the trait.
|
||||
///
|
||||
/// It is not required that the value is constant.
|
||||
pub trait TypedGet {
|
||||
/// The type which is returned.
|
||||
type Type;
|
||||
/// Return the current value.
|
||||
fn get() -> Self::Type;
|
||||
}
|
||||
|
||||
/// A trait for querying a single value from a type.
|
||||
///
|
||||
/// It is not required that the value is constant.
|
||||
pub trait Get<T> {
|
||||
/// Return the current value.
|
||||
fn get() -> T;
|
||||
}
|
||||
|
||||
impl<T: Default> Get<T> for () {
|
||||
fn get() -> T {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement Get by returning Default for any type that implements Default.
|
||||
pub struct GetDefault;
|
||||
impl<T: Default> Get<T> for GetDefault {
|
||||
fn get() -> T {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Try and collect into a collection `C`.
|
||||
pub trait TryCollect<C> {
|
||||
/// The error type that gets returned when a collection can't be made from `self`.
|
||||
type Error;
|
||||
/// Consume self and try to collect the results into `C`.
|
||||
///
|
||||
/// This is useful in preventing the undesirable `.collect().try_into()` call chain on
|
||||
/// collections that need to be converted into a bounded type (e.g. `BoundedVec`).
|
||||
fn try_collect(self) -> Result<C, Self::Error>;
|
||||
}
|
||||
|
||||
macro_rules! impl_const_get {
|
||||
($name:ident, $t:ty) => {
|
||||
#[doc = "Const getter for a basic type."]
|
||||
#[derive($crate::RuntimeDebug)]
|
||||
pub struct $name<const T: $t>;
|
||||
impl<const T: $t> Get<$t> for $name<T> {
|
||||
fn get() -> $t {
|
||||
T
|
||||
}
|
||||
}
|
||||
impl<const T: $t> Get<Option<$t>> for $name<T> {
|
||||
fn get() -> Option<$t> {
|
||||
Some(T)
|
||||
}
|
||||
}
|
||||
impl<const T: $t> TypedGet for $name<T> {
|
||||
type Type = $t;
|
||||
fn get() -> $t {
|
||||
T
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_const_get!(ConstBool, bool);
|
||||
impl_const_get!(ConstU8, u8);
|
||||
impl_const_get!(ConstU16, u16);
|
||||
impl_const_get!(ConstU32, u32);
|
||||
impl_const_get!(ConstU64, u64);
|
||||
impl_const_get!(ConstU128, u128);
|
||||
impl_const_get!(ConstI8, i8);
|
||||
impl_const_get!(ConstI16, i16);
|
||||
impl_const_get!(ConstI32, i32);
|
||||
impl_const_get!(ConstI64, i64);
|
||||
impl_const_get!(ConstI128, i128);
|
||||
|
||||
/// Create new implementations of the [`Get`](crate::traits::Get) trait.
|
||||
///
|
||||
/// The so-called parameter type can be created in four different ways:
|
||||
///
|
||||
/// - Using `const` to create a parameter type that provides a `const` getter. It is required that
|
||||
/// the `value` is const.
|
||||
///
|
||||
/// - Declare the parameter type without `const` to have more freedom when creating the value.
|
||||
///
|
||||
/// NOTE: A more substantial version of this macro is available in `frame_support` crate which
|
||||
/// allows mutable and persistant variants.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use sp_runtime::traits::Get;
|
||||
/// # use sp_runtime::parameter_types;
|
||||
/// // This function cannot be used in a const context.
|
||||
/// fn non_const_expression() -> u64 { 99 }
|
||||
///
|
||||
/// const FIXED_VALUE: u64 = 10;
|
||||
/// parameter_types! {
|
||||
/// pub const Argument: u64 = 42 + FIXED_VALUE;
|
||||
/// /// Visibility of the type is optional
|
||||
/// OtherArgument: u64 = non_const_expression();
|
||||
/// }
|
||||
///
|
||||
/// trait Config {
|
||||
/// type Parameter: Get<u64>;
|
||||
/// type OtherParameter: Get<u64>;
|
||||
/// }
|
||||
///
|
||||
/// struct Runtime;
|
||||
/// impl Config for Runtime {
|
||||
/// type Parameter = Argument;
|
||||
/// type OtherParameter = OtherArgument;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Invalid example:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// # use sp_runtime::traits::Get;
|
||||
/// # use sp_runtime::parameter_types;
|
||||
/// // This function cannot be used in a const context.
|
||||
/// fn non_const_expression() -> u64 { 99 }
|
||||
///
|
||||
/// parameter_types! {
|
||||
/// pub const Argument: u64 = non_const_expression();
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! parameter_types {
|
||||
(
|
||||
$( #[ $attr:meta ] )*
|
||||
$vis:vis const $name:ident: $type:ty = $value:expr;
|
||||
$( $rest:tt )*
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!(@IMPL_CONST $name , $type , $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
(
|
||||
$( #[ $attr:meta ] )*
|
||||
$vis:vis $name:ident: $type:ty = $value:expr;
|
||||
$( $rest:tt )*
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!(@IMPL $name, $type, $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
() => ();
|
||||
(@IMPL_CONST $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the value of this parameter type.
|
||||
pub const fn get() -> $type {
|
||||
$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::traits::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from(Self::get())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::traits::TypedGet for $name {
|
||||
type Type = $type;
|
||||
fn get() -> $type {
|
||||
Self::get()
|
||||
}
|
||||
}
|
||||
};
|
||||
(@IMPL $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the value of this parameter type.
|
||||
pub fn get() -> $type {
|
||||
$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::traits::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from(Self::get())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::traits::TypedGet for $name {
|
||||
type Type = $type;
|
||||
fn get() -> $type {
|
||||
Self::get()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Extensible conversion trait. Generic over only source type, with destination type being
|
||||
/// associated.
|
||||
pub trait Morph<A> {
|
||||
|
||||
Reference in New Issue
Block a user