Skip to content

Commit

Permalink
simplify some bounds and add a dev note
Browse files Browse the repository at this point in the history
  • Loading branch information
jsdw committed Nov 9, 2023
1 parent 9cc1ebf commit 050a0ae
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 36 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"scale-decode-derive",
"testing/no_std",
]
resolver = "2"

[workspace.package]
version = "0.9.0"
Expand Down
7 changes: 7 additions & 0 deletions scale-decode/src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ impl From<DecodeError> for Error {
}
}

impl From<codec::Error> for Error {
fn from(err: codec::Error) -> Error {
let err: DecodeError = err.into();
Error::new(err.into())
}
}

/// The underlying nature of the error.
#[derive(Debug, derive_more::From, derive_more::Display)]
pub enum ErrorKind {
Expand Down
43 changes: 9 additions & 34 deletions scale-decode/src/impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ macro_rules! impl_decode_seq_via_collect {
impl <$generic> Visitor for BasicVisitor<$ty<$generic>>
where
$generic: IntoVisitor,
Error: From<<$generic::Visitor as Visitor>::Error>,
$( $($where)* )?
{
type Value<'scale, 'info> = $ty<$generic>;
Expand Down Expand Up @@ -306,11 +305,7 @@ macro_rules! array_method_impl {
Ok(arr)
}};
}
impl<const N: usize, T> Visitor for BasicVisitor<[T; N]>
where
T: IntoVisitor,
Error: From<<T::Visitor as Visitor>::Error>,
{
impl<const N: usize, T: IntoVisitor> Visitor for BasicVisitor<[T; N]> {
type Value<'scale, 'info> = [T; N];
type Error = Error;

Expand All @@ -331,22 +326,14 @@ where

visit_single_field_composite_tuple_impls!();
}
impl<const N: usize, T> IntoVisitor for [T; N]
where
T: IntoVisitor,
Error: From<<T::Visitor as Visitor>::Error>,
{
impl<const N: usize, T: IntoVisitor> IntoVisitor for [T; N] {
type Visitor = BasicVisitor<[T; N]>;
fn into_visitor() -> Self::Visitor {
BasicVisitor { _marker: core::marker::PhantomData }
}
}

impl<T> Visitor for BasicVisitor<BTreeMap<String, T>>
where
T: IntoVisitor,
Error: From<<T::Visitor as Visitor>::Error>,
{
impl<T: IntoVisitor> Visitor for BasicVisitor<BTreeMap<String, T>> {
type Error = Error;
type Value<'scale, 'info> = BTreeMap<String, T>;

Expand Down Expand Up @@ -375,11 +362,7 @@ where
}
impl_into_visitor!(BTreeMap<String, T>);

impl<T> Visitor for BasicVisitor<Option<T>>
where
T: IntoVisitor,
Error: From<<T::Visitor as Visitor>::Error>,
{
impl<T: IntoVisitor> Visitor for BasicVisitor<Option<T>> {
type Error = Error;
type Value<'scale, 'info> = Option<T>;

Expand Down Expand Up @@ -409,13 +392,7 @@ where
}
impl_into_visitor!(Option<T>);

impl<T, E> Visitor for BasicVisitor<Result<T, E>>
where
T: IntoVisitor,
Error: From<<T::Visitor as Visitor>::Error>,
E: IntoVisitor,
Error: From<<E::Visitor as Visitor>::Error>,
{
impl<T: IntoVisitor, E: IntoVisitor> Visitor for BasicVisitor<Result<T, E>> {
type Error = Error;
type Value<'scale, 'info> = Result<T, E>;

Expand Down Expand Up @@ -595,7 +572,6 @@ macro_rules! impl_decode_tuple {
impl < $($t),* > Visitor for BasicVisitor<($($t,)*)>
where $(
$t: IntoVisitor,
Error: From<<$t::Visitor as Visitor>::Error>,
)*
{
type Value<'scale, 'info> = ($($t,)*);
Expand Down Expand Up @@ -623,7 +599,7 @@ macro_rules! impl_decode_tuple {

// We can turn this tuple into a visitor which knows how to decode it:
impl < $($t),* > IntoVisitor for ($($t,)*)
where $( $t: IntoVisitor, Error: From<<$t::Visitor as Visitor>::Error>, )*
where $( $t: IntoVisitor, )*
{
type Visitor = BasicVisitor<($($t,)*)>;
fn into_visitor() -> Self::Visitor {
Expand All @@ -633,7 +609,7 @@ macro_rules! impl_decode_tuple {

// We can decode given a list of fields (just delegate to the visitor impl:
impl < $($t),* > DecodeAsFields for ($($t,)*)
where $( $t: IntoVisitor, Error: From<<$t::Visitor as Visitor>::Error>, )*
where $( $t: IntoVisitor, )*
{
fn decode_as_fields<'info>(input: &mut &[u8], fields: &mut dyn FieldIter<'info>, types: &'info scale_info::PortableRegistry) -> Result<Self, Error> {
let mut composite = crate::visitor::types::Composite::new(input, crate::EMPTY_SCALE_INFO_PATH, fields, types, false);
Expand Down Expand Up @@ -678,7 +654,6 @@ fn decode_items_using<'a, 'scale, 'info, D: DecodeItemIterator<'scale, 'info>, T
) -> impl Iterator<Item = Result<T, Error>> + 'a
where
T: IntoVisitor,
Error: From<<T::Visitor as Visitor>::Error>,
D: DecodeItemIterator<'scale, 'info>,
{
let mut idx = 0;
Expand Down Expand Up @@ -712,7 +687,7 @@ mod test {
fn assert_encode_decode_to_with<T, A, B>(a: &A, b: &B)
where
A: Encode,
B: DecodeAsType + PartialEq + core::fmt::Debug,
B: IntoVisitor + PartialEq + core::fmt::Debug,
T: scale_info::TypeInfo + 'static,
{
let (type_id, types) = make_type::<T>();
Expand All @@ -726,7 +701,7 @@ mod test {
fn assert_encode_decode_to<A, B>(a: &A, b: &B)
where
A: Encode + scale_info::TypeInfo + 'static,
B: DecodeAsType + PartialEq + core::fmt::Debug,
B: IntoVisitor + PartialEq + core::fmt::Debug,
{
assert_encode_decode_to_with::<A, A, B>(a, b);
}
Expand Down
9 changes: 7 additions & 2 deletions scale-decode/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,13 @@ pub trait FieldIter<'a>: Iterator<Item = Field<'a>> {}
impl<'a, T> FieldIter<'a> for T where T: Iterator<Item = Field<'a>> {}

/// This trait can be implemented on any type that has an associated [`Visitor`] responsible for decoding
/// SCALE encoded bytes to it. Anything that implements this trait gets a [`DecodeAsType`] implementation
/// for free.
/// SCALE encoded bytes to it whose error type is [`Error`]. Anything that implements this trait gets a
/// [`DecodeAsType`] implementation for free.
// Dev note: This used to allow for any Error type that could be converted into `scale_decode::Error`.
// The problem with this is that the `DecodeAsType` trait became tricky to use in some contexts, because it
// didn't automatically imply so much. Realistically, being stricter here shouldn't matter too much; derive
// impls all use `scale_decode::Error` anyway, and manual impls can just manually convert into the error
// rather than rely on auto conversion, if they care about also being able to impl `DecodeAsType`.
pub trait IntoVisitor {
/// The visitor type used to decode SCALE encoded bytes to `Self`.
type Visitor: for<'scale, 'info> visitor::Visitor<Value<'scale, 'info> = Self, Error = Error>;
Expand Down

0 comments on commit 050a0ae

Please sign in to comment.