Remove derive_more (#1600)

* replace derive_more's 'From' in signer

* replace derive_more's 'From' in core

* Remove `derive_more`'s `Display` usages (#1601)

* Remove derive_more's 'Display' from core

* Remove derive_more's 'Display' from metadata

* Remove derive_more's 'Display' from signer

* Remove derive_more from dependencies (#1602)

closes #1503

* Update signer/src/eth.rs

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* rename convert_error to impl_from

* rename convert_error to impl_from in core

---------

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
This commit is contained in:
Pavlo Khrystenko
2024-05-24 11:18:51 +02:00
committed by GitHub
parent ae5c0927c6
commit 5a0682c1e0
14 changed files with 239 additions and 98 deletions
Generated
-3
View File
@@ -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",
-1
View File
@@ -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"] }
-1
View File
@@ -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"] }
+125 -55
View File
@@ -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<scale_decode::visitor::DecodeError> 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<dyn CustomError>),
}
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 {}
+10
View File
@@ -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};
+14 -6
View File
@@ -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 {}
-1
View File
@@ -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"] }
+26 -7
View File
@@ -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 {}
-1
View File
@@ -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 }
+11 -3
View File
@@ -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 {}
+15 -9
View File
@@ -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 {}
+13 -4
View File
@@ -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<M: AsRef<[u8]>>(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 {}
+15 -7
View File
@@ -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<M: AsRef<[u8]>>(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 {}
+10
View File
@@ -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())
}
}
};
}