diff --git a/Cargo.lock b/Cargo.lock index 589b07377b..ef503c9755 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4855,7 +4855,6 @@ dependencies = [ "bitvec", "blake2", "derive-where", - "derive_more", "frame-metadata 16.0.0", "hashbrown 0.14.5", "hex", @@ -4924,7 +4923,6 @@ dependencies = [ "assert_matches", "bitvec", "criterion", - "derive_more", "frame-metadata 16.0.0", "hashbrown 0.14.5", "parity-scale-codec", @@ -4939,7 +4937,6 @@ dependencies = [ "bip32", "bip39", "cfg-if", - "derive_more", "getrandom", "hex", "hex-literal", diff --git a/Cargo.toml b/Cargo.toml index 865b1e3241..47e054a3e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,6 @@ color-eyre = "0.6.3" console_error_panic_hook = "0.1.7" darling = "0.20.8" derive-where = "1.2.7" -derive_more = "0.99.17" either = { version = "1.11.0", default-features = false } frame-metadata = { version = "16.0.0", default-features = false } futures = { version = "0.3.30", default-features = false, features = ["std"] } diff --git a/core/Cargo.toml b/core/Cargo.toml index e1e08f1fea..7e6019ff61 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -45,7 +45,6 @@ scale-encode = { workspace = true, default-features = false, features = ["derive frame-metadata = { workspace = true, default-features = false } subxt-metadata = { workspace = true, default-features = false } derive-where = { workspace = true } -derive_more = { workspace = true } hex = { workspace = true, default-features = false, features = ["alloc"] } serde = { workspace = true, default-features = false, features = ["derive"] } serde_json = { workspace = true, default-features = false, features = ["raw_value", "alloc"] } diff --git a/core/src/error.rs b/core/src/error.rs index f9f8b0a629..9824c49a84 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -4,134 +4,168 @@ //! The errors that can be emitted in this crate. +use core::fmt::Display; + use alloc::boxed::Box; use alloc::string::String; -use derive_more::{Display, From}; use subxt_metadata::StorageHasher; /// The error emitted when something goes wrong. -#[derive(Debug, Display, From)] +#[derive(Debug)] pub enum Error { /// Codec error. - #[display(fmt = "Scale codec error: {_0}")] Codec(codec::Error), /// Metadata error. - #[display(fmt = "Metadata Error: {_0}")] Metadata(MetadataError), /// Storage address error. - #[display(fmt = "Storage Error: {_0}")] StorageAddress(StorageAddressError), /// Error decoding to a [`crate::dynamic::Value`]. - #[display(fmt = "Error decoding into dynamic value: {_0}")] Decode(scale_decode::Error), /// Error encoding from a [`crate::dynamic::Value`]. - #[display(fmt = "Error encoding from dynamic value: {_0}")] Encode(scale_encode::Error), /// Error constructing the appropriate extrinsic params. - #[display(fmt = "Extrinsic params error: {_0}")] ExtrinsicParams(ExtrinsicParamsError), /// Block body error. - #[display(fmt = "Error working with block body: {_0}")] Block(BlockError), } +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Codec(e) => write!(f, "Scale codec error: {e}"), + Error::Metadata(e) => write!(f, "Metadata Error: {e}"), + Error::StorageAddress(e) => write!(f, "Storage Error: {e}"), + Error::Decode(e) => write!(f, "Error decoding into dynamic value: {e}"), + Error::Encode(e) => write!(f, "Error encoding from dynamic value: {e}"), + Error::ExtrinsicParams(e) => write!(f, "Extrinsic params error: {e}"), + Error::Block(e) => write!(f, "Error working with block_body: {}", e), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for Error {} -impl From for Error { - fn from(value: scale_decode::visitor::DecodeError) -> Self { - Error::Decode(value.into()) - } -} +impl_from!(ExtrinsicParamsError => Error::ExtrinsicParams); +impl_from!(BlockError => Error::Block); +impl_from!(MetadataError => Error::Metadata); +impl_from!(scale_decode::Error => Error::Decode); +impl_from!(scale_decode::visitor::DecodeError => Error::Decode); +impl_from!(scale_encode::Error => Error::Encode); +impl_from!(StorageAddressError => Error::StorageAddress); +impl_from!(codec::Error => Error::Codec); /// Block error -#[derive(Clone, Debug, Display, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum BlockError { /// Extrinsic type ID cannot be resolved with the provided metadata. - #[display( - fmt = "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata" - )] MissingType, /// Unsupported signature. - #[display(fmt = "Unsupported extrinsic version, only version 4 is supported currently")] /// The extrinsic has an unsupported version. UnsupportedVersion(u8), /// Decoding error. - #[display(fmt = "Cannot decode extrinsic: {_0}")] DecodingError(codec::Error), } +impl Display for BlockError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + BlockError::MissingType => write!(f, "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata"), + BlockError::UnsupportedVersion(_) => write!(f, "Unsupported extrinsic version, only version 4 is supported currently"), + BlockError::DecodingError(e) => write!(f, "Cannot decode extrinsic: {e}"), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for BlockError {} /// Something went wrong trying to access details in the metadata. -#[derive(Clone, Debug, PartialEq, Display)] +#[derive(Clone, Debug, PartialEq)] #[non_exhaustive] pub enum MetadataError { /// The DispatchError type isn't available in the metadata - #[display(fmt = "The DispatchError type isn't available")] DispatchErrorNotFound, /// Type not found in metadata. - #[display(fmt = "Type with ID {_0} not found")] TypeNotFound(u32), /// Pallet not found (index). - #[display(fmt = "Pallet with index {_0} not found")] PalletIndexNotFound(u8), /// Pallet not found (name). - #[display(fmt = "Pallet with name {_0} not found")] PalletNameNotFound(String), /// Variant not found. - #[display(fmt = "Variant with index {_0} not found")] VariantIndexNotFound(u8), /// Constant not found. - #[display(fmt = "Constant with name {_0} not found")] ConstantNameNotFound(String), /// Call not found. - #[display(fmt = "Call with name {_0} not found")] CallNameNotFound(String), /// Runtime trait not found. - #[display(fmt = "Runtime trait with name {_0} not found")] RuntimeTraitNotFound(String), /// Runtime method not found. - #[display(fmt = "Runtime method with name {_0} not found")] RuntimeMethodNotFound(String), /// Call type not found in metadata. - #[display(fmt = "Call type not found in pallet with index {_0}")] CallTypeNotFoundInPallet(u8), /// Event type not found in metadata. - #[display(fmt = "Event type not found in pallet with index {_0}")] EventTypeNotFoundInPallet(u8), /// Storage details not found in metadata. - #[display(fmt = "Storage details not found in pallet with name {_0}")] StorageNotFoundInPallet(String), /// Storage entry not found. - #[display(fmt = "Storage entry {_0} not found")] StorageEntryNotFound(String), /// The generated interface used is not compatible with the node. - #[display(fmt = "The generated code is not compatible with the node")] IncompatibleCodegen, /// Custom value not found. - #[display(fmt = "Custom value with name {_0} not found")] CustomValueNameNotFound(String), } +impl Display for MetadataError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + MetadataError::DispatchErrorNotFound => { + write!(f, "The DispatchError type isn't available") + } + MetadataError::TypeNotFound(e) => write!(f, "Type with ID {e} not found"), + MetadataError::PalletIndexNotFound(e) => write!(f, "Pallet with index {e} not found"), + MetadataError::PalletNameNotFound(e) => write!(f, "Pallet with name {e} not found"), + MetadataError::VariantIndexNotFound(e) => write!(f, "Variant with index {e} not found"), + MetadataError::ConstantNameNotFound(e) => write!(f, "Constant with name {e} not found"), + MetadataError::CallNameNotFound(e) => write!(f, "Call with name {e} not found"), + MetadataError::RuntimeTraitNotFound(e) => { + write!(f, "Runtime trait with name {e} not found") + } + MetadataError::RuntimeMethodNotFound(e) => { + write!(f, "Runtime method with name {e} not found") + } + MetadataError::CallTypeNotFoundInPallet(e) => { + write!(f, "Call type not found in pallet with index {e}") + } + MetadataError::EventTypeNotFoundInPallet(e) => { + write!(f, "Event type not found in pallet with index {e}") + } + MetadataError::StorageNotFoundInPallet(e) => { + write!(f, "Storage details not found in pallet with name {e}") + } + MetadataError::StorageEntryNotFound(e) => write!(f, "Storage entry {e} not found"), + MetadataError::IncompatibleCodegen => { + write!(f, "The generated code is not compatible with the node") + } + MetadataError::CustomValueNameNotFound(e) => { + write!(f, "Custom value with name {e} not found") + } + } + } +} #[cfg(feature = "std")] impl std::error::Error for MetadataError {} /// Something went wrong trying to encode or decode a storage address. -#[derive(Clone, Debug, Display)] +#[derive(Clone, Debug)] #[non_exhaustive] pub enum StorageAddressError { /// Storage lookup does not have the expected number of keys. - #[display(fmt = "Storage lookup requires {expected} keys but more keys have been provided.")] TooManyKeys { /// The number of keys provided in the storage address. expected: usize, }, /// This storage entry in the metadata does not have the correct number of hashers to fields. - #[display( - fmt = "Storage entry in metadata does not have the correct number of hashers to fields" - )] WrongNumberOfHashers { /// The number of hashers in the metadata for this storage entry. hashers: usize, @@ -139,20 +173,12 @@ pub enum StorageAddressError { fields: usize, }, /// We weren't given enough bytes to decode the storage address/key. - #[display(fmt = "Not enough remaining bytes to decode the storage address/key")] NotEnoughBytes, /// We have leftover bytes after decoding the storage address. - #[display(fmt = "We have leftover bytes after decoding the storage address")] TooManyBytes, /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. - #[display( - fmt = "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata" - )] UnexpectedAddressBytes, /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. - #[display( - fmt = "An invalid hasher was used to reconstruct a value with type ID {ty_id} from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher" - )] HasherCannotReconstructKey { /// Type id of the key's type. ty_id: u32, @@ -161,17 +187,47 @@ pub enum StorageAddressError { }, } +impl Display for StorageAddressError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + StorageAddressError::TooManyKeys { expected } => write!( + f, + "Storage lookup requires {expected} keys but more keys have been provided." + ), + StorageAddressError::WrongNumberOfHashers { .. } => write!( + f, + "Storage entry in metadata does not have the correct number of hashers to fields" + ), + StorageAddressError::NotEnoughBytes => write!( + f, + "Not enough remaining bytes to decode the storage address/key" + ), + StorageAddressError::TooManyBytes => write!( + f, + "We have leftover bytes after decoding the storage address" + ), + StorageAddressError::UnexpectedAddressBytes => write!( + f, + "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata" + ), + StorageAddressError::HasherCannotReconstructKey { ty_id, hasher } => write!( + f, + "An invalid hasher was used to reconstruct a value with type ID {ty_id} from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher" + ), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for StorageAddressError {} /// An error that can be emitted when trying to construct an instance of [`crate::config::ExtrinsicParams`], /// encode data from the instance, or match on signed extensions. -#[derive(Display, Debug)] +#[derive(Debug)] #[non_exhaustive] pub enum ExtrinsicParamsError { /// Cannot find a type id in the metadata. The context provides some additional /// information about the source of the error (eg the signed extension name). - #[display(fmt = "Cannot find type id '{type_id} in the metadata (context: {context})")] MissingTypeId { /// Type ID. type_id: u32, @@ -179,15 +235,29 @@ pub enum ExtrinsicParamsError { context: &'static str, }, /// A signed extension in use on some chain was not provided. - #[display( - fmt = "The chain expects a signed extension with the name {_0}, but we did not provide one" - )] UnknownSignedExtension(String), /// Some custom error. - #[display(fmt = "Error constructing extrinsic parameters: {_0}")] Custom(Box), } +impl Display for ExtrinsicParamsError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + ExtrinsicParamsError::MissingTypeId { type_id, context } => write!( + f, + "Cannot find type id '{type_id} in the metadata (context: {context})" + ), + ExtrinsicParamsError::UnknownSignedExtension(e) => write!( + f, + "The chain expects a signed extension with the name {e}, but we did not provide one" + ), + ExtrinsicParamsError::Custom(e) => { + write!(f, "Error constructing extrinsic parameters: {e}") + } + } + } +} + /// Anything implementing this trait can be used in [`ExtrinsicParamsError::Custom`]. #[cfg(feature = "std")] pub trait CustomError: std::error::Error + Send + Sync + 'static {} diff --git a/core/src/macros.rs b/core/src/macros.rs index 8e25742c88..7b0117c959 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -18,4 +18,14 @@ macro_rules! cfg_substrate_compat { }; } +macro_rules! impl_from { + ($module_path:path => $delegate_ty:ident :: $variant:ident) => { + impl From<$module_path> for $delegate_ty { + fn from(val: $module_path) -> Self { + $delegate_ty::$variant(val.into()) + } + } + }; +} + pub(crate) use {cfg_feature, cfg_substrate_compat}; diff --git a/core/src/utils/account_id.rs b/core/src/utils/account_id.rs index d5cd65d6b6..008455bd39 100644 --- a/core/src/utils/account_id.rs +++ b/core/src/utils/account_id.rs @@ -6,12 +6,13 @@ //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_core::AccountId32` //! for instance, to gain functionality without forcing a dependency on Substrate crates here. +use core::fmt::Display; + use alloc::format; use alloc::string::String; use alloc::vec; use alloc::vec::Vec; use codec::{Decode, Encode}; -use derive_more::Display; use serde::{Deserialize, Serialize}; /// A 32-byte cryptographic identifier. This is a simplified version of Substrate's @@ -105,19 +106,26 @@ impl AccountId32 { } /// An error obtained from trying to interpret an SS58 encoded string into an AccountId32 -#[derive(Clone, Copy, Eq, PartialEq, Debug, Display)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] #[allow(missing_docs)] pub enum FromSs58Error { - #[display(fmt = "Base 58 requirement is violated")] BadBase58, - #[display(fmt = "Length is bad")] BadLength, - #[display(fmt = "Invalid checksum")] InvalidChecksum, - #[display(fmt = "Invalid SS58 prefix byte.")] InvalidPrefix, } +impl Display for FromSs58Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + FromSs58Error::BadBase58 => write!(f, "Base 58 requirement is violated"), + FromSs58Error::BadLength => write!(f, "Length is bad"), + FromSs58Error::InvalidChecksum => write!(f, "Invalid checksum"), + FromSs58Error::InvalidPrefix => write!(f, "Invalid SS58 prefix byte."), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for FromSs58Error {} diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index 1423122ed5..b080adb8b5 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -23,7 +23,6 @@ frame-metadata = { workspace = true, default-features = false, features = ["curr codec = { package = "parity-scale-codec", workspace = true, default-features = false, features = ["derive"] } sp-crypto-hashing = { workspace = true } hashbrown = { workspace = true } -derive_more = { workspace = true } [dev-dependencies] bitvec = { workspace = true, features = ["alloc"] } diff --git a/metadata/src/from_into/mod.rs b/metadata/src/from_into/mod.rs index 1a950e1d5a..13bb2f40c2 100644 --- a/metadata/src/from_into/mod.rs +++ b/metadata/src/from_into/mod.rs @@ -2,34 +2,53 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. +use core::fmt::Display; + use alloc::string::String; -use derive_more::Display; mod v14; mod v15; /// An error emitted if something goes wrong converting [`frame_metadata`] /// types into [`crate::Metadata`]. -#[derive(Debug, Display, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] #[non_exhaustive] pub enum TryFromError { /// Type missing from type registry - #[display(fmt = "Type id {_0} is expected but not found in the type registry")] TypeNotFound(u32), /// Type was not a variant/enum type - #[display(fmt = "Type {_0} was not a variant/enum type, but is expected to be one")] VariantExpected(u32), /// An unsupported metadata version was provided. - #[display(fmt = "Cannot convert v{_0} metadata into Metadata type")] UnsupportedMetadataVersion(u32), /// Type name missing from type registry - #[display(fmt = "Type name {_0} is expected but not found in the type registry")] TypeNameNotFound(String), /// Invalid type path. - #[display(fmt = "Type has an invalid path {_0}")] InvalidTypePath(String), } +impl Display for TryFromError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + TryFromError::TypeNotFound(e) => write!( + f, + "Type id {e} is expected but not found in the type registry" + ), + TryFromError::VariantExpected(e) => write!( + f, + "Type {e} was not a variant/enum type, but is expected to be one" + ), + TryFromError::UnsupportedMetadataVersion(e) => { + write!(f, "Cannot convert v{e} metadata into Metadata type") + } + TryFromError::TypeNameNotFound(e) => write!( + f, + "Type name {e} is expected but not found in the type registry" + ), + TryFromError::InvalidTypePath(e) => write!(f, "Type has an invalid path {e}"), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for TryFromError {} diff --git a/signer/Cargo.toml b/signer/Cargo.toml index ddd6517d9d..5461fac007 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -52,7 +52,6 @@ hex = { workspace = true, features = ["alloc"] } cfg-if = { workspace = true } codec = { package = "parity-scale-codec", workspace = true, features = ["derive"] } sp-crypto-hashing = { workspace = true } -derive_more = { workspace = true } pbkdf2 = { workspace = true } sha2 = { workspace = true } hmac = { workspace = true } diff --git a/signer/src/crypto/secret_uri.rs b/signer/src/crypto/secret_uri.rs index 5148311795..dd287d2874 100644 --- a/signer/src/crypto/secret_uri.rs +++ b/signer/src/crypto/secret_uri.rs @@ -2,9 +2,10 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. +use core::fmt::Display; + use super::DeriveJunction; use alloc::vec::Vec; -use derive_more::Display; use regex::Regex; use secrecy::SecretString; @@ -117,13 +118,20 @@ impl core::str::FromStr for SecretUri { } /// This is returned if `FromStr` cannot parse a string into a `SecretUri`. -#[derive(Debug, Copy, Clone, PartialEq, Display)] +#[derive(Debug, Copy, Clone, PartialEq)] pub enum SecretUriError { /// Parsing the secret URI from a string failed; wrong format. - #[display(fmt = "Invalid secret phrase format")] InvalidFormat, } +impl Display for SecretUriError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SecretUriError::InvalidFormat => write!(f, "Invalid secret phrase format"), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for SecretUriError {} diff --git a/signer/src/ecdsa.rs b/signer/src/ecdsa.rs index e5b6c4507c..82c4d2f70d 100644 --- a/signer/src/ecdsa.rs +++ b/signer/src/ecdsa.rs @@ -6,8 +6,7 @@ use codec::Encode; use crate::crypto::{seed_from_entropy, DeriveJunction, SecretUri}; -use core::str::FromStr; -use derive_more::{Display, From}; +use core::{fmt::Display, str::FromStr}; use hex::FromHex; use secp256k1::{ecdsa::RecoverableSignature, Message, Secp256k1, SecretKey}; use secrecy::ExposeSecret; @@ -217,23 +216,30 @@ pub(crate) mod internal { } /// An error handed back if creating a keypair fails. -#[derive(Debug, PartialEq, Display, From)] +#[derive(Debug, PartialEq)] pub enum Error { /// Invalid seed. - #[display(fmt = "Invalid seed (was it the wrong length?)")] - #[from(ignore)] InvalidSeed, /// Invalid seed. - #[display(fmt = "Invalid seed for ECDSA, contained soft junction")] - #[from(ignore)] SoftJunction, /// Invalid phrase. - #[display(fmt = "Cannot parse phrase: {_0}")] Phrase(bip39::Error), /// Invalid hex. - #[display(fmt = "Cannot parse hex string: {_0}")] Hex(hex::FromHexError), } +impl Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::InvalidSeed => write!(f, "Invalid seed (was it the wrong length?)"), + Error::SoftJunction => write!(f, "Invalid seed for ECDSA, contained soft junction"), + Error::Phrase(e) => write!(f, "Cannot parse phrase: {e}"), + Error::Hex(e) => write!(f, "Cannot parse hex string: {e}"), + } + } +} + +impl_from!(bip39::Error => Error::Phrase); +impl_from!(hex::FromHexError => Error::Hex); #[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/signer/src/eth.rs b/signer/src/eth.rs index 2096c8a192..0d4d8a6b49 100644 --- a/signer/src/eth.rs +++ b/signer/src/eth.rs @@ -9,7 +9,6 @@ use alloc::format; use alloc::string::String; use core::fmt::{Display, Formatter}; use core::str::FromStr; -use derive_more::Display; use keccak_hash::keccak; use secp256k1::Message; @@ -217,16 +216,26 @@ pub fn verify>(sig: &Signature, message: M, pubkey: &ecdsa::Publi } /// An error handed back if creating a keypair fails. -#[derive(Debug, PartialEq, Display)] +#[derive(Debug, PartialEq)] pub enum Error { /// Invalid seed. - #[display(fmt = "Invalid seed (was it the wrong length?)")] InvalidSeed, /// Invalid derivation path. - #[display(fmt = "Could not derive from path; some valeus in the path may have been >= 2^31?")] DeriveFromPath, } +impl Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + Error::InvalidSeed => write!(f, "Invalid seed (was it the wrong length?)"), + Error::DeriveFromPath => write!( + f, + "Could not derive from path; some values in the path may have been >= 2^31?" + ), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/signer/src/sr25519.rs b/signer/src/sr25519.rs index 9848cbdd68..2a9eb84ecd 100644 --- a/signer/src/sr25519.rs +++ b/signer/src/sr25519.rs @@ -4,11 +4,10 @@ //! An sr25519 keypair implementation. -use core::str::FromStr; +use core::{fmt::Display, str::FromStr}; use crate::crypto::{seed_from_entropy, DeriveJunction, SecretUri}; -use derive_more::{Display, From}; use hex::FromHex; use schnorrkel::{ derive::{ChainCode, Derivation}, @@ -192,20 +191,29 @@ pub fn verify>(sig: &Signature, message: M, pubkey: &PublicKey) - } /// An error handed back if creating a keypair fails. -#[derive(Debug, Display, From)] +#[derive(Debug)] pub enum Error { /// Invalid seed. - #[display(fmt = "Invalid seed (was it the wrong length?)")] - #[from(ignore)] InvalidSeed, /// Invalid phrase. - #[display(fmt = "Cannot parse phrase: {_0}")] Phrase(bip39::Error), /// Invalid hex. - #[display(fmt = "Cannot parse hex string: {_0}")] Hex(hex::FromHexError), } +impl_from!(bip39::Error => Error::Phrase); +impl_from!(hex::FromHexError => Error::Hex); + +impl Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::InvalidSeed => write!(f, "Invalid seed (was it the wrong length?)"), + Error::Phrase(e) => write!(f, "Cannot parse phrase: {e}"), + Error::Hex(e) => write!(f, "Cannot parse hex string: {e}"), + } + } +} + #[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/signer/src/utils.rs b/signer/src/utils.rs index e3cea3cfc8..89d261e3b9 100644 --- a/signer/src/utils.rs +++ b/signer/src/utils.rs @@ -34,3 +34,13 @@ macro_rules! once_static_cloned { )+ }; } + +macro_rules! impl_from { + ($module_path:path => $delegate_ty:ident :: $variant:ident) => { + impl From<$module_path> for $delegate_ty { + fn from(val: $module_path) -> Self { + $delegate_ty::$variant(val.into()) + } + } + }; +}