From 29b0954cb0a609e1412174aabc8c21006d262f81 Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 13:38:29 +0200
Subject: [PATCH 01/13] wrapper: fix support for FromHex derivation

---
 src/wrapper.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/wrapper.rs b/src/wrapper.rs
index 771c9ba..7089cf3 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -123,6 +123,7 @@ impl FromPath for Wrapper {
                     "Display" => Some(Wrapper::Display),
                     "Debug" => Some(Wrapper::Debug),
                     "Octal" => Some(Wrapper::Octal),
+                    "FromHex" => Some(Wrapper::FromHex),
                     "LowerHex" => Some(Wrapper::LowerHex),
                     "UpperHex" => Some(Wrapper::UpperHex),
                     "LowerExp" => Some(Wrapper::LowerExp),

From 4359ca73b26075fad1a156c07f34f4fd3ea671fe Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 14:27:14 +0200
Subject: [PATCH 02/13] wrapper: allow to skip AsRef, AsMut, Borrow and
 BorrowMut implementations

---
 src/lib.rs     |   2 +
 src/wrapper.rs | 120 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 82 insertions(+), 40 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index b42e166..2b0c351 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -648,6 +648,7 @@ pub fn derive_getters(input: TokenStream) -> TokenStream {
 /// * `amplify::Wrapper`
 /// * [`AsRef`]
 /// * [`core::borrow::Borrow`]
+/// You may skip `AsRef` and `Borrow` implementations with `#[wrapper(NoRefs)]`.
 ///
 /// You can implement additional derives, it they are implemented for the
 /// wrapped type, using `#[wrapper()]` proc macro:
@@ -775,6 +776,7 @@ pub fn derive_wrapper(input: TokenStream) -> TokenStream {
 /// * `amplify::WrapperMut`
 /// * [`AsMut`]
 /// * [`core::borrow::BorrowMut`]
+/// You may skip `AsMut` and `BorrowMut` implementations with `#[wrapper_mut(NoRefs)]`.
 ///
 /// You can implement additional derives, it they are implemented for the
 /// wrapped type, using `#[wrapper()]` proc macro:
diff --git a/src/wrapper.rs b/src/wrapper.rs
index 7089cf3..b260387 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -24,8 +24,9 @@ use crate::util::get_amplify_crate;
 const NAME: &str = "wrapper";
 const EXAMPLE: &str = r#"#[wrapper(LowerHex, Add)]"#;
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
 enum Wrapper {
+    NoRefs,
     // Formatting
     FromStr,
     Display,
@@ -38,6 +39,8 @@ enum Wrapper {
     UpperExp,
     // References
     Deref,
+    AsRef,
+    Borrow,
     BorrowSlice,
     // Indexes
     Index,
@@ -71,10 +74,13 @@ enum Wrapper {
     BitOps,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
 enum WrapperMut {
+    NoRefs,
     // References
     DerefMut,
+    AsMut,
+    BorrowMut,
     BorrowSliceMut,
     // Indexes
     IndexMut,
@@ -103,9 +109,12 @@ enum WrapperMut {
     BitAssign,
 }
 
-pub trait FromPath: Sized + Copy {
+pub trait FromPath: Sized + Copy + Ord {
     const IDENT: &'static str;
     const DERIVE: &'static str;
+    const NO_REFS: Self;
+    fn default_set() -> Vec<Self>;
+    fn is_not_ref(&self) -> bool;
     fn from_path(path: &Path) -> Result<Option<Self>>;
     fn populate(self, list: &mut Vec<Self>);
 }
@@ -113,6 +122,15 @@ pub trait FromPath: Sized + Copy {
 impl FromPath for Wrapper {
     const IDENT: &'static str = "wrapper";
     const DERIVE: &'static str = "Wrapper";
+    const NO_REFS: Self = Self::NoRefs;
+
+    fn default_set() -> Vec<Self> {
+        vec![Wrapper::AsRef, Wrapper::Borrow]
+    }
+
+    fn is_not_ref(&self) -> bool {
+        *self != Wrapper::AsRef && *self != Wrapper::Borrow
+    }
 
     fn from_path(path: &Path) -> Result<Option<Self>> {
         path.segments.first().map_or(
@@ -128,7 +146,10 @@ impl FromPath for Wrapper {
                     "UpperHex" => Some(Wrapper::UpperHex),
                     "LowerExp" => Some(Wrapper::LowerExp),
                     "UpperExp" => Some(Wrapper::UpperExp),
+                    "NoRefs" => Some(Wrapper::NoRefs),
+                    "AsRef" => Some(Wrapper::AsRef),
                     "Deref" => Some(Wrapper::Deref),
+                    "Borrow" => Some(Wrapper::Borrow),
                     "BorrowSlice" => Some(Wrapper::BorrowSlice),
                     "Index" => Some(Wrapper::Index),
                     "IndexRange" => Some(Wrapper::IndexRange),
@@ -339,6 +360,26 @@ impl Wrapper {
                     }
                 }
             },
+            Wrapper::AsRef => quote! {
+                #[automatically_derived]
+                impl #impl_generics ::core::convert::AsRef<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                    #[inline]
+                    fn as_ref(&self) -> &<Self as #amplify_crate::Wrapper>::Inner {
+                        use #amplify_crate::Wrapper;
+                        Wrapper::as_inner(self)
+                    }
+                }
+            },
+            Wrapper::Borrow => quote! {
+                #[automatically_derived]
+                impl #impl_generics ::core::borrow::Borrow<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                    #[inline]
+                    fn borrow(&self) -> &<Self as #amplify_crate::Wrapper>::Inner {
+                        use #amplify_crate::Wrapper;
+                        Wrapper::as_inner(self)
+                    }
+                }
+            },
             Wrapper::BorrowSlice => quote! {
                 #[automatically_derived]
                 impl #impl_generics ::core::borrow::Borrow<[u8]> for #ident_name #ty_generics #where_clause
@@ -623,13 +664,25 @@ impl Wrapper {
 impl FromPath for WrapperMut {
     const IDENT: &'static str = "wrapper_mut";
     const DERIVE: &'static str = "WrapperMut";
+    const NO_REFS: Self = Self::NoRefs;
+
+    fn default_set() -> Vec<Self> {
+        vec![WrapperMut::AsMut, WrapperMut::BorrowMut]
+    }
+
+    fn is_not_ref(&self) -> bool {
+        *self != WrapperMut::AsMut && *self != WrapperMut::BorrowMut
+    }
 
     fn from_path(path: &Path) -> Result<Option<Self>> {
         path.segments.first().map_or(
             Err(attr_err!(path.span(), NAME, "must contain at least one identifier", EXAMPLE)),
             |segment| {
                 Ok(match segment.ident.to_string().as_str() {
+                    "NoRefs" => Some(WrapperMut::NoRefs),
                     "DerefMut" => Some(WrapperMut::DerefMut),
+                    "AsMut" => Some(WrapperMut::AsMut),
+                    "BorrowMut" => Some(WrapperMut::BorrowMut),
                     "BorrowSliceMut" => Some(WrapperMut::BorrowSliceMut),
                     "IndexMut" => Some(WrapperMut::IndexMut),
                     "IndexRangeMut" => Some(WrapperMut::IndexRangeMut),
@@ -715,6 +768,26 @@ impl WrapperMut {
                     }
                 }
             },
+            WrapperMut::AsMut => quote! {
+                #[automatically_derived]
+                impl #impl_generics ::core::convert::AsMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                    #[inline]
+                    fn as_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
+                        use #amplify_crate::WrapperMut;
+                        WrapperMut::as_inner_mut(self)
+                    }
+                }
+            },
+            WrapperMut::BorrowMut => quote! {
+                #[automatically_derived]
+                impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                    #[inline]
+                    fn borrow_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
+                        use #amplify_crate::WrapperMut;
+                        WrapperMut::as_inner_mut(self)
+                    }
+                }
+            },
             WrapperMut::BorrowSliceMut => quote! {
                 #[automatically_derived]
                 impl #impl_generics ::core::borrow::BorrowMut<[u8]> for #ident_name #ty_generics #where_clause
@@ -976,24 +1049,6 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
             }
         }
 
-        #[automatically_derived]
-        impl #impl_generics ::core::convert::AsRef<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
-            #[inline]
-            fn as_ref(&self) -> &<Self as #amplify_crate::Wrapper>::Inner {
-                use #amplify_crate::Wrapper;
-                Wrapper::as_inner(self)
-            }
-        }
-
-        #[automatically_derived]
-        impl #impl_generics ::core::borrow::Borrow<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
-            #[inline]
-            fn borrow(&self) -> &<Self as #amplify_crate::Wrapper>::Inner {
-                use #amplify_crate::Wrapper;
-                Wrapper::as_inner(self)
-            }
-        }
-
         #( #wrapper_derive )*
     })
 }
@@ -1017,24 +1072,6 @@ pub(crate) fn inner_mut(input: DeriveInput) -> Result<TokenStream2> {
             }
         }
 
-        #[automatically_derived]
-        impl #impl_generics ::core::convert::AsMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
-            #[inline]
-            fn as_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
-                use #amplify_crate::WrapperMut;
-                WrapperMut::as_inner_mut(self)
-            }
-        }
-
-        #[automatically_derived]
-        impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
-            #[inline]
-            fn borrow_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
-                use #amplify_crate::WrapperMut;
-                WrapperMut::as_inner_mut(self)
-            }
-        }
-
         #( #wrapper_derive )*
     })
 }
@@ -1120,7 +1157,7 @@ fn get_params(input: &DeriveInput) -> Result<(TokenStream2, Type)> {
 }
 
 fn get_wrappers<T: FromPath>(input: &DeriveInput) -> Result<Vec<T>> {
-    let mut wrappers = vec![];
+    let mut wrappers = T::default_set();
     const WRAPPER_DERIVE_ERR: &str = "Wrapper attributes must be in a form of type list";
     for attr in input
         .attrs
@@ -1146,5 +1183,8 @@ fn get_wrappers<T: FromPath>(input: &DeriveInput) -> Result<Vec<T>> {
             _ => return Err(attr_err!(attr, WRAPPER_DERIVE_ERR)),
         }
     }
+    if wrappers.contains(&T::NO_REFS) {
+        wrappers = wrappers.into_iter().filter(T::is_not_ref).collect();
+    }
     Ok(wrappers)
 }

From b1db1b7c46e944a53b8d9ced0b003860904a7a6e Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 14:27:27 +0200
Subject: [PATCH 03/13] wrapper: add AsSlice and AsSliceMut wrappers

---
 src/lib.rs     |  2 ++
 src/wrapper.rs | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/src/lib.rs b/src/lib.rs
index 2b0c351..20b7801 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -654,6 +654,7 @@ pub fn derive_getters(input: TokenStream) -> TokenStream {
 /// wrapped type, using `#[wrapper()]` proc macro:
 /// 1. Reference access to the inner type:
 ///    * `Deref` for implementing [`core::ops::Deref`]
+///    * `AsSlice` for implementing [`AsRef`]`<[u8]>`
 ///    * `BorrowSlice` for implementing
 ///      [`core::borrow::Borrow`]`<[Self::Inner]>`
 /// 2. Formatting:
@@ -782,6 +783,7 @@ pub fn derive_wrapper(input: TokenStream) -> TokenStream {
 /// wrapped type, using `#[wrapper()]` proc macro:
 /// 1. Reference access to the inner type:
 ///    * `DerefMut` for implementing [`core::ops::DerefMut`]
+///    * `AsSliceMut` for implementing [`AsMut`]`<[u8]>`
 ///    * `BorrowSliceMut` for implementing
 ///      [`core::borrow::BorrowMut`]`<[Self::Inner]>`
 /// 2. Indexed access to the inner type:
diff --git a/src/wrapper.rs b/src/wrapper.rs
index b260387..2402e4f 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -40,6 +40,7 @@ enum Wrapper {
     // References
     Deref,
     AsRef,
+    AsSlice,
     Borrow,
     BorrowSlice,
     // Indexes
@@ -80,6 +81,7 @@ enum WrapperMut {
     // References
     DerefMut,
     AsMut,
+    AsSliceMut,
     BorrowMut,
     BorrowSliceMut,
     // Indexes
@@ -148,6 +150,7 @@ impl FromPath for Wrapper {
                     "UpperExp" => Some(Wrapper::UpperExp),
                     "NoRefs" => Some(Wrapper::NoRefs),
                     "AsRef" => Some(Wrapper::AsRef),
+                    "AsSlice" => Some(Wrapper::AsSlice),
                     "Deref" => Some(Wrapper::Deref),
                     "Borrow" => Some(Wrapper::Borrow),
                     "BorrowSlice" => Some(Wrapper::BorrowSlice),
@@ -370,6 +373,17 @@ impl Wrapper {
                     }
                 }
             },
+            Wrapper::AsSlice => quote! {
+                #[automatically_derived]
+                impl #impl_generics AsRef<[u8]> for #ident_name #ty_generics #where_clause
+                {
+                    #[inline]
+                    fn as_ref(&self) -> &[u8] {
+                        use #amplify_crate::Wrapper;
+                        AsRef::<[u8]>::as_ref(Wrapper::as_inner(self))
+                    }
+                }
+            },
             Wrapper::Borrow => quote! {
                 #[automatically_derived]
                 impl #impl_generics ::core::borrow::Borrow<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
@@ -682,6 +696,7 @@ impl FromPath for WrapperMut {
                     "NoRefs" => Some(WrapperMut::NoRefs),
                     "DerefMut" => Some(WrapperMut::DerefMut),
                     "AsMut" => Some(WrapperMut::AsMut),
+                    "AsSliceMut" => Some(WrapperMut::AsSliceMut),
                     "BorrowMut" => Some(WrapperMut::BorrowMut),
                     "BorrowSliceMut" => Some(WrapperMut::BorrowSliceMut),
                     "IndexMut" => Some(WrapperMut::IndexMut),
@@ -778,6 +793,17 @@ impl WrapperMut {
                     }
                 }
             },
+            WrapperMut::AsSliceMut => quote! {
+                #[automatically_derived]
+                impl #impl_generics AsMut<[u8]> for #ident_name #ty_generics #where_clause
+                {
+                    #[inline]
+                    fn as_mut(&mut self) -> &mut [u8] {
+                        use #amplify_crate::WrapperMut;
+                        AsMut::<[u8]>::as_mut(WrapperMut::as_inner_mut(self))
+                    }
+                }
+            },
             WrapperMut::BorrowMut => quote! {
                 #[automatically_derived]
                 impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {

From 49378230c8427dfbfe7198787e3e724381a428b6 Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 16:38:11 +0200
Subject: [PATCH 04/13] wrapper: access inner type directly

---
 src/wrapper.rs | 212 ++++++++++++++++++++-----------------------------
 1 file changed, 85 insertions(+), 127 deletions(-)

diff --git a/src/wrapper.rs b/src/wrapper.rs
index 2402e4f..e9cbff1 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -235,7 +235,12 @@ impl FromPath for Wrapper {
 }
 
 impl Wrapper {
-    pub fn into_token_stream2(self, input: &DeriveInput) -> TokenStream2 {
+    pub fn into_token_stream2(
+        self,
+        input: &DeriveInput,
+        from: &Type,
+        field: &TokenStream2,
+    ) -> TokenStream2 {
         let impl_generics_params = input.generics.params.clone();
         let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
         let ident_name = &input.ident;
@@ -251,10 +256,7 @@ impl Wrapper {
                     #[inline]
                     fn from_str(s: &str) -> Result<Self, Self::Err> {
                         use ::core::str::FromStr;
-                        use #amplify_crate::Wrapper;
-                        Ok(Wrapper::from_inner(
-                            <Self as #amplify_crate::Wrapper>::Inner::from_str(s)?,
-                        ))
+                        FromStr::from_str(s).map(Self::from)
                     }
                 }
             },
@@ -264,8 +266,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::Display::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::Display::fmt(&self.#field, f)
                     }
                 }
             },
@@ -275,8 +276,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::Debug::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::Debug::fmt(&self.#field, f)
                     }
                 }
             },
@@ -286,8 +286,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::Octal::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::Octal::fmt(&self.#field, f)
                     }
                 }
             },
@@ -302,8 +301,7 @@ impl Wrapper {
                             + ExactSizeIterator
                             + DoubleEndedIterator,
                     {
-                        use #amplify_crate::Wrapper;
-                        <Self as Wrapper>::Inner::from_byte_iter(iter).map(Self::from_inner)
+                        #amplify_crate::hex::FromHex::from_byte_iter(iter).map(Self::from)
                     }
                 }
             },
@@ -313,8 +311,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::LowerHex::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::LowerHex::fmt(&self.#field, f)
                     }
                 }
             },
@@ -324,8 +321,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::UpperHex::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::UpperHex::fmt(&self.#field, f)
                     }
                 }
             },
@@ -335,8 +331,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::LowerExp::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::LowerExp::fmt(&self.#field, f)
                     }
                 }
             },
@@ -346,8 +341,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
-                        use #amplify_crate::Wrapper;
-                        ::core::fmt::UpperExp::fmt(Wrapper::as_inner(self), f)
+                        ::core::fmt::UpperExp::fmt(&self.#field, f)
                     }
                 }
             },
@@ -355,21 +349,19 @@ impl Wrapper {
                 #[automatically_derived]
                 impl #impl_generics ::core::ops::Deref for #ident_name #ty_generics #where_clause
                 {
-                    type Target = <Self as #amplify_crate::Wrapper>::Inner;
+                    type Target = #from;
                     #[inline]
                     fn deref(&self) -> &Self::Target {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::as_inner(self)
+                        &self.#field
                     }
                 }
             },
             Wrapper::AsRef => quote! {
                 #[automatically_derived]
-                impl #impl_generics ::core::convert::AsRef<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                impl #impl_generics ::core::convert::AsRef<#from> for #ident_name #ty_generics #where_clause {
                     #[inline]
-                    fn as_ref(&self) -> &<Self as #amplify_crate::Wrapper>::Inner {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::as_inner(self)
+                    fn as_ref(&self) -> &#from {
+                        &self.#field
                     }
                 }
             },
@@ -386,11 +378,10 @@ impl Wrapper {
             },
             Wrapper::Borrow => quote! {
                 #[automatically_derived]
-                impl #impl_generics ::core::borrow::Borrow<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                impl #impl_generics ::core::borrow::Borrow<#from> for #ident_name #ty_generics #where_clause {
                     #[inline]
-                    fn borrow(&self) -> &<Self as #amplify_crate::Wrapper>::Inner {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::as_inner(self)
+                    fn borrow(&self) -> &#from {
+                        &self.#field
                     }
                 }
             },
@@ -400,8 +391,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn borrow(&self) -> &[u8] {
-                        use #amplify_crate::Wrapper;
-                        ::core::borrow::Borrow::<[u8]>::borrow(Wrapper::as_inner(self))
+                        ::core::borrow::Borrow::<[u8]>::borrow(&self.#field)
                     }
                 }
             },
@@ -414,12 +404,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<usize> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<usize>>::Output;
+                        type Output = <#from as ::core::ops::Index<usize>>::Output;
 
                         #[inline]
                         fn index(&self, index: usize) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -429,12 +418,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<::core::ops::Range<usize>> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<::core::ops::Range<usize>>>::Output;
+                        type Output = <#from as ::core::ops::Index<::core::ops::Range<usize>>>::Output;
 
                         #[inline]
                         fn index(&self, index: ::core::ops::Range<usize>) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -444,12 +432,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeFrom<usize>> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<::core::ops::RangeFrom<usize>>>::Output;
+                        type Output = <#from as ::core::ops::Index<::core::ops::RangeFrom<usize>>>::Output;
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -459,12 +446,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeTo<usize>> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<::core::ops::RangeTo<usize>>>::Output;
+                        type Output = <#from as ::core::ops::Index<::core::ops::RangeTo<usize>>>::Output;
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeTo<usize>) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -474,12 +460,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeInclusive<usize>> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<::core::ops::RangeInclusive<usize>>>::Output;
+                        type Output = <#from as ::core::ops::Index<::core::ops::RangeInclusive<usize>>>::Output;
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeInclusive<usize>) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -489,12 +474,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeToInclusive<usize>> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<::core::ops::RangeInclusive<usize>>>::Output;
+                        type Output = <#from as ::core::ops::Index<::core::ops::RangeInclusive<usize>>>::Output;
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeToInclusive<usize>) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -504,12 +488,11 @@ impl Wrapper {
                     #[automatically_derived]
                     impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeFull> for #ident_name #ty_generics #where_clause
                     {
-                        type Output = <<Self as #amplify_crate::Wrapper>::Inner as ::core::ops::Index<::core::ops::RangeFull>>::Output;
+                        type Output = <#from as ::core::ops::Index<::core::ops::RangeFull>>::Output;
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeFull) -> &Self::Output {
-                            use #amplify_crate::Wrapper;
-                            Wrapper::as_inner(self).index(index)
+                            self.#from.index(index)
                         }
                     }
                 }
@@ -522,8 +505,7 @@ impl Wrapper {
 
                     #[inline]
                     fn neg(self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Neg::neg(Wrapper::into_inner(self)))
+                        Self { #field: ::core::ops::Neg::neg(self.#field) }
                     }
                 }
             },
@@ -535,8 +517,7 @@ impl Wrapper {
 
                     #[inline]
                     fn not(self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Not::not(Wrapper::into_inner(self)))
+                        Self { #field: ::core::ops::Not::not(Wrapper::into_inner(self)) }
                     }
                 }
             },
@@ -548,8 +529,7 @@ impl Wrapper {
 
                     #[inline]
                     fn add(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Add::add(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Add::add(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -561,8 +541,7 @@ impl Wrapper {
 
                     #[inline]
                     fn sub(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Sub::sub(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Sub::sub(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -574,8 +553,7 @@ impl Wrapper {
 
                     #[inline]
                     fn mul(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Mul::mul(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Mul::mul(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -587,8 +565,7 @@ impl Wrapper {
 
                     #[inline]
                     fn div(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Div::div(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Div::div(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -600,8 +577,7 @@ impl Wrapper {
 
                     #[inline]
                     fn rem(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Rem::rem(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Rem::rem(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -613,8 +589,7 @@ impl Wrapper {
 
                     #[inline]
                     fn shl(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Shl::shl(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Shl::shl(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -626,8 +601,7 @@ impl Wrapper {
 
                     #[inline]
                     fn shr(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::Shr::shr(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::Shr::shr(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -639,8 +613,7 @@ impl Wrapper {
 
                     #[inline]
                     fn bitand(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::BitAnd::bitand(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::BitAnd::bitand(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -652,8 +625,7 @@ impl Wrapper {
 
                     #[inline]
                     fn bitor(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::BitOr::bitor(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::BitOr::bitor(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -665,8 +637,7 @@ impl Wrapper {
 
                     #[inline]
                     fn bitxor(self, rhs: Self) -> Self {
-                        use #amplify_crate::Wrapper;
-                        Wrapper::from_inner(::core::ops::BitXor::bitxor(Wrapper::into_inner(self), rhs.into_inner()))
+                        Self { #field: ::core::ops::BitXor::bitxor(Wrapper::into_inner(self), rhs.into_inner()) }
                     }
                 }
             },
@@ -765,7 +736,12 @@ impl FromPath for WrapperMut {
 }
 
 impl WrapperMut {
-    pub fn into_token_stream2(self, input: &DeriveInput) -> TokenStream2 {
+    pub fn into_token_stream2(
+        self,
+        input: &DeriveInput,
+        _from: &Type,
+        field: &TokenStream2,
+    ) -> TokenStream2 {
         let impl_generics_params = input.generics.params.clone();
         let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
         let ident_name = &input.ident;
@@ -778,8 +754,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn deref_mut(&mut self) -> &mut Self::Target {
-                        use #amplify_crate::WrapperMut;
-                        WrapperMut::as_inner_mut(self)
+                        &mut self.#field
                     }
                 }
             },
@@ -788,8 +763,7 @@ impl WrapperMut {
                 impl #impl_generics ::core::convert::AsMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
                     #[inline]
                     fn as_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
-                        use #amplify_crate::WrapperMut;
-                        WrapperMut::as_inner_mut(self)
+                        &mut self.#field
                     }
                 }
             },
@@ -799,8 +773,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn as_mut(&mut self) -> &mut [u8] {
-                        use #amplify_crate::WrapperMut;
-                        AsMut::<[u8]>::as_mut(WrapperMut::as_inner_mut(self))
+                        &mut self.#field
                     }
                 }
             },
@@ -809,8 +782,7 @@ impl WrapperMut {
                 impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
                     #[inline]
                     fn borrow_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
-                        use #amplify_crate::WrapperMut;
-                        WrapperMut::as_inner_mut(self)
+                        &mut self.#field
                     }
                 }
             },
@@ -820,8 +792,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn borrow_mut(&mut self) -> &mut [u8] {
-                        use #amplify_crate::WrapperMut;
-                        ::core::borrow::BorrowMut::<[u8]>::borrow_mut(WrapperMut::as_inner_mut(self))
+                        &mut self.#field
                     }
                 }
             },
@@ -836,8 +807,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: usize) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -849,8 +819,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: ::core::ops::Range<usize>) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -862,8 +831,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: ::core::ops::RangeFrom<usize>) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -875,8 +843,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: ::core::ops::RangeTo<usize>) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -888,8 +855,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: ::core::ops::RangeInclusive<usize>) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -901,8 +867,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: ::core::ops::RangeToInclusive<usize>) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -914,8 +879,7 @@ impl WrapperMut {
                     {
                         #[inline]
                         fn index_mut(&mut self, index: ::core::ops::RangeFull) -> &mut Self::Output {
-                            use #amplify_crate::WrapperMut;
-                            WrapperMut::as_inner_mut(self).index_mut(index)
+                            self.as_mut().index_mut(index)
                         }
                     }
                 }
@@ -926,8 +890,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn add_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::AddAssign::add_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::AddAssign::add_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -937,8 +900,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn sub_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::SubAssign::sub_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::SubAssign::sub_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -948,8 +910,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn mul_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::MulAssign::mul_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::MulAssign::mul_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -959,8 +920,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn div_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::DivAssign::div_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::DivAssign::div_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -970,8 +930,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn rem_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::RemAssign::rem_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::RemAssign::rem_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -981,8 +940,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn shl_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::ShlAssign::shl_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::ShlAssign::shl_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -992,8 +950,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn shr_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::ShrAssign::shr_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::ShrAssign::shr_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -1003,8 +960,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn bitand_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::BitAndAssign::bitand_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::BitAndAssign::bitand_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -1014,8 +970,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn bitor_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::BitOrAssign::bitor_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::BitOrAssign::bitor_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -1025,8 +980,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn bitxor_assign(&mut self, rhs: Self) {
-                        use #amplify_crate::{Wrapper, WrapperMut};
-                        ::core::ops::BitXorAssign::bitxor_assign(WrapperMut::as_inner_mut(self), rhs.into_inner())
+                        ::core::ops::BitXorAssign::bitxor_assign(self.#field, rhs.#field)
                     }
                 }
             },
@@ -1043,7 +997,9 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
     let (field, from) = get_params(&input)?;
 
     let wrappers = get_wrappers::<Wrapper>(&input)?;
-    let wrapper_derive = wrappers.iter().map(|w| w.into_token_stream2(&input));
+    let wrapper_derive = wrappers
+        .iter()
+        .map(|w| w.into_token_stream2(&input, &from, &field));
 
     Ok(quote! {
         #[automatically_derived]
@@ -1084,10 +1040,12 @@ pub(crate) fn inner_mut(input: DeriveInput) -> Result<TokenStream2> {
     let ident_name = &input.ident;
     let amplify_crate = get_amplify_crate(&input);
 
-    let (field, _from) = get_params(&input)?;
+    let (field, from) = get_params(&input)?;
 
     let wrappers = get_wrappers::<WrapperMut>(&input)?;
-    let wrapper_derive = wrappers.iter().map(|w| w.into_token_stream2(&input));
+    let wrapper_derive = wrappers
+        .iter()
+        .map(|w| w.into_token_stream2(&input, &from, &field));
 
     Ok(quote! {
         #[automatically_derived]

From f5a4a1b31bc6696bf5a21b639df3b0709c6d17ca Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 16:40:11 +0200
Subject: [PATCH 05/13] wrapper: improve match

---
 src/wrapper.rs | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/wrapper.rs b/src/wrapper.rs
index e9cbff1..2879d69 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -641,7 +641,14 @@ impl Wrapper {
                     }
                 }
             },
-            _ => unreachable!(),
+            Wrapper::NoRefs
+            | Wrapper::Hex
+            | Wrapper::Exp
+            | Wrapper::NumberFmt
+            | Wrapper::RangeOps
+            | Wrapper::MathOps
+            | Wrapper::BoolOps
+            | Wrapper::BitOps => unreachable!(),
         }
     }
 }
@@ -984,7 +991,11 @@ impl WrapperMut {
                     }
                 }
             },
-            _ => unreachable!(),
+            WrapperMut::NoRefs
+            | WrapperMut::RangeMut
+            | WrapperMut::MathAssign
+            | WrapperMut::BoolAssign
+            | WrapperMut::BitAssign => unreachable!(),
         }
     }
 }

From 8a6ef55d2ec1460d598b856e098c11af7d6cee1f Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 17:04:30 +0200
Subject: [PATCH 06/13] wrapper: fix FromStr implementation

---
 src/lib.rs     | 2 +-
 src/wrapper.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 20b7801..80572b3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -836,7 +836,7 @@ pub fn derive_wrapper(input: TokenStream) -> TokenStream {
 ///     Display
 /// )]
 /// #[display(inner)]
-/// #[wrapper(NumberFmt, MathOps, BoolOps)]
+/// #[wrapper(NumberFmt, MathOps, BoolOps, FromStr)]
 /// #[wrapper_mut(MathAssign, BitAssign)]
 /// struct Int64(i64);
 /// ```
diff --git a/src/wrapper.rs b/src/wrapper.rs
index 2879d69..1fef17c 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -256,7 +256,7 @@ impl Wrapper {
                     #[inline]
                     fn from_str(s: &str) -> Result<Self, Self::Err> {
                         use ::core::str::FromStr;
-                        FromStr::from_str(s).map(Self::from)
+                        <#from as FromStr>::from_str(s).map(Self::from)
                     }
                 }
             },

From bfdefb95ebd566049ed817f95e4f7ac88a4f514f Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 17:20:15 +0200
Subject: [PATCH 07/13] wrapper: access field directly

---
 src/wrapper.rs | 62 ++++++++++++++++++++++++--------------------------
 1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/src/wrapper.rs b/src/wrapper.rs
index 1fef17c..2821cd3 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -371,8 +371,7 @@ impl Wrapper {
                 {
                     #[inline]
                     fn as_ref(&self) -> &[u8] {
-                        use #amplify_crate::Wrapper;
-                        AsRef::<[u8]>::as_ref(Wrapper::as_inner(self))
+                        AsRef::<[u8]>::as_ref(&self.#field)
                     }
                 }
             },
@@ -408,7 +407,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: usize) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -422,7 +421,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: ::core::ops::Range<usize>) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -436,7 +435,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -450,7 +449,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeTo<usize>) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -464,7 +463,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeInclusive<usize>) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -478,7 +477,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeToInclusive<usize>) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -492,7 +491,7 @@ impl Wrapper {
 
                         #[inline]
                         fn index(&self, index: ::core::ops::RangeFull) -> &Self::Output {
-                            self.#from.index(index)
+                            self.#field.index(index)
                         }
                     }
                 }
@@ -517,7 +516,7 @@ impl Wrapper {
 
                     #[inline]
                     fn not(self) -> Self {
-                        Self { #field: ::core::ops::Not::not(Wrapper::into_inner(self)) }
+                        Self { #field: ::core::ops::Not::not(self.#field) }
                     }
                 }
             },
@@ -529,7 +528,7 @@ impl Wrapper {
 
                     #[inline]
                     fn add(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Add::add(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Add::add(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -541,7 +540,7 @@ impl Wrapper {
 
                     #[inline]
                     fn sub(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Sub::sub(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Sub::sub(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -553,7 +552,7 @@ impl Wrapper {
 
                     #[inline]
                     fn mul(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Mul::mul(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Mul::mul(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -565,7 +564,7 @@ impl Wrapper {
 
                     #[inline]
                     fn div(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Div::div(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Div::div(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -577,7 +576,7 @@ impl Wrapper {
 
                     #[inline]
                     fn rem(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Rem::rem(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Rem::rem(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -589,7 +588,7 @@ impl Wrapper {
 
                     #[inline]
                     fn shl(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Shl::shl(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Shl::shl(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -601,7 +600,7 @@ impl Wrapper {
 
                     #[inline]
                     fn shr(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::Shr::shr(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::Shr::shr(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -613,7 +612,7 @@ impl Wrapper {
 
                     #[inline]
                     fn bitand(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::BitAnd::bitand(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::BitAnd::bitand(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -625,7 +624,7 @@ impl Wrapper {
 
                     #[inline]
                     fn bitor(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::BitOr::bitor(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::BitOr::bitor(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -637,7 +636,7 @@ impl Wrapper {
 
                     #[inline]
                     fn bitxor(self, rhs: Self) -> Self {
-                        Self { #field: ::core::ops::BitXor::bitxor(Wrapper::into_inner(self), rhs.into_inner()) }
+                        Self { #field: ::core::ops::BitXor::bitxor(self.#field, rhs.#field) }
                     }
                 }
             },
@@ -897,7 +896,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn add_assign(&mut self, rhs: Self) {
-                        ::core::ops::AddAssign::add_assign(self.#field, rhs.#field)
+                        ::core::ops::AddAssign::add_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -907,7 +906,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn sub_assign(&mut self, rhs: Self) {
-                        ::core::ops::SubAssign::sub_assign(self.#field, rhs.#field)
+                        ::core::ops::SubAssign::sub_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -917,7 +916,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn mul_assign(&mut self, rhs: Self) {
-                        ::core::ops::MulAssign::mul_assign(self.#field, rhs.#field)
+                        ::core::ops::MulAssign::mul_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -927,7 +926,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn div_assign(&mut self, rhs: Self) {
-                        ::core::ops::DivAssign::div_assign(self.#field, rhs.#field)
+                        ::core::ops::DivAssign::div_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -937,7 +936,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn rem_assign(&mut self, rhs: Self) {
-                        ::core::ops::RemAssign::rem_assign(self.#field, rhs.#field)
+                        ::core::ops::RemAssign::rem_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -947,7 +946,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn shl_assign(&mut self, rhs: Self) {
-                        ::core::ops::ShlAssign::shl_assign(self.#field, rhs.#field)
+                        ::core::ops::ShlAssign::shl_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -957,7 +956,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn shr_assign(&mut self, rhs: Self) {
-                        ::core::ops::ShrAssign::shr_assign(self.#field, rhs.#field)
+                        ::core::ops::ShrAssign::shr_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -967,7 +966,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn bitand_assign(&mut self, rhs: Self) {
-                        ::core::ops::BitAndAssign::bitand_assign(self.#field, rhs.#field)
+                        ::core::ops::BitAndAssign::bitand_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -977,7 +976,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn bitor_assign(&mut self, rhs: Self) {
-                        ::core::ops::BitOrAssign::bitor_assign(self.#field, rhs.#field)
+                        ::core::ops::BitOrAssign::bitor_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -987,7 +986,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn bitxor_assign(&mut self, rhs: Self) {
-                        ::core::ops::BitXorAssign::bitxor_assign(self.#field, rhs.#field)
+                        ::core::ops::BitXorAssign::bitxor_assign(&mut self.#field, rhs.#field)
                     }
                 }
             },
@@ -1037,8 +1036,7 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
         impl #impl_generics ::core::convert::From<#ident_name #ty_generics> for #from #where_clause {
             #[inline]
             fn from(wrapped: #ident_name #ty_generics) -> Self {
-                use #amplify_crate::Wrapper;
-                Wrapper::into_inner(wrapped)
+                wrapped.#field
             }
         }
 

From f8aeec38136c4a0dfad5bf0499d77fb22cb5a22d Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 17:22:50 +0200
Subject: [PATCH 08/13] wrapper: fix FromHex implementation

---
 src/wrapper.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/wrapper.rs b/src/wrapper.rs
index 2821cd3..4d9b102 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -301,7 +301,7 @@ impl Wrapper {
                             + ExactSizeIterator
                             + DoubleEndedIterator,
                     {
-                        #amplify_crate::hex::FromHex::from_byte_iter(iter).map(Self::from)
+                        <#from as #amplify_crate::hex::FromHex>::from_byte_iter(iter).map(Self::from)
                     }
                 }
             },

From 9ca1b8af3269a24a1aa75c158ce1e672aa56cdec Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 20:06:42 +0200
Subject: [PATCH 09/13] wrapper: fix mutable slice borrowings

---
 src/wrapper.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/wrapper.rs b/src/wrapper.rs
index 4d9b102..5c642c2 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -779,7 +779,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn as_mut(&mut self) -> &mut [u8] {
-                        &mut self.#field
+                        AsMut::<[u8]>::as_mut(&mut self.#field)
                     }
                 }
             },
@@ -798,7 +798,7 @@ impl WrapperMut {
                 {
                     #[inline]
                     fn borrow_mut(&mut self) -> &mut [u8] {
-                        &mut self.#field
+                        ::core::borrow::BorrowMut::<[u8]>::borrow_mut(&mut self.#field)
                     }
                 }
             },

From ee16f2829d3804ff37dd51edf435d6051ad7e636 Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Mon, 9 Oct 2023 13:51:03 +0200
Subject: [PATCH 10/13] chore: update dependencies to fix ci

---
 Cargo.lock | 120 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 64 insertions(+), 56 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 1d15ff7..3804f8e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,11 +4,11 @@ version = 3
 
 [[package]]
 name = "amplify"
-version = "4.0.0"
+version = "4.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26966af46e0d200e8bf2b7f16230997c1c3f2d141bc27ccc091c012ed527b58"
+checksum = "213783efd41ed08b2861e86dd5aac633cf612f861e9222ace8b3621bd58af5c6"
 dependencies = [
- "amplify_derive 3.0.0",
+ "amplify_derive 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "amplify_num",
  "ascii",
  "wasm-bindgen",
@@ -16,26 +16,26 @@ dependencies = [
 
 [[package]]
 name = "amplify_derive"
-version = "3.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "580f12b79a9e10cfa8d2515128d83a53f387e290096a75904c92b8a2a4d542a6"
+version = "3.0.1"
 dependencies = [
- "amplify_syn 2.0.0",
+ "amplify",
+ "amplify_syn 2.0.1",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.109",
+ "wasm-bindgen-test",
 ]
 
 [[package]]
 name = "amplify_derive"
 version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c87df0f28e6eb1f2d355f29ba6793fa9ca643967528609608d5cbd70bd68f9d1"
 dependencies = [
- "amplify",
- "amplify_syn 2.0.1",
+ "amplify_syn 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2",
  "quote",
- "syn",
- "wasm-bindgen-test",
+ "syn 1.0.109",
 ]
 
 [[package]]
@@ -46,22 +46,22 @@ checksum = "ddce3bc63e807ea02065e8d8b702695f3d302ae4158baddff8b0ce5c73947251"
 
 [[package]]
 name = "amplify_syn"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29b08d74fda406d5a94abfdcdb91ba13bb06562ccf0a4581867fa924ca242b01"
+version = "2.0.1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.109",
 ]
 
 [[package]]
 name = "amplify_syn"
 version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7736fb8d473c0d83098b5bac44df6a561e20470375cd8bcae30516dc889fd62a"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.109",
 ]
 
 [[package]]
@@ -72,9 +72,9 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
 
 [[package]]
 name = "bumpalo"
-version = "3.12.0"
+version = "3.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
+checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
 
 [[package]]
 name = "cfg-if"
@@ -94,42 +94,39 @@ dependencies = [
 
 [[package]]
 name = "js-sys"
-version = "0.3.60"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
 dependencies = [
  "wasm-bindgen",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.17"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
-dependencies = [
- "cfg-if",
-]
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 
 [[package]]
 name = "once_cell"
-version = "1.17.0"
+version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.50"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.23"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
 dependencies = [
  "proc-macro2",
 ]
@@ -142,9 +139,20 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
 
 [[package]]
 name = "syn"
-version = "1.0.107"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -153,15 +161,15 @@ dependencies = [
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.6"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
 dependencies = [
  "cfg-if",
  "wasm-bindgen-macro",
@@ -169,24 +177,24 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.38",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.33"
+version = "0.4.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
 dependencies = [
  "cfg-if",
  "js-sys",
@@ -196,9 +204,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -206,28 +214,28 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.38",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "wasm-bindgen-test"
-version = "0.3.33"
+version = "0.3.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d"
+checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671"
 dependencies = [
  "console_error_panic_hook",
  "js-sys",
@@ -239,9 +247,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-test-macro"
-version = "0.3.33"
+version = "0.3.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7"
+checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -249,9 +257,9 @@ dependencies = [
 
 [[package]]
 name = "web-sys"
-version = "0.3.60"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
 dependencies = [
  "js-sys",
  "wasm-bindgen",

From 8b3cba92e1433516e269d97699a9d86f98473799 Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Mon, 9 Oct 2023 13:55:28 +0200
Subject: [PATCH 11/13] chore: run cargo fmt

---
 .rustfmt.toml   |  6 +++---
 src/lib.rs      |  3 ++-
 src/wrapper.rs  | 42 +++++++++++++++++-------------------------
 syn/src/attr.rs |  4 ++--
 4 files changed, 24 insertions(+), 31 deletions(-)

diff --git a/.rustfmt.toml b/.rustfmt.toml
index 952a284..18425d7 100644
--- a/.rustfmt.toml
+++ b/.rustfmt.toml
@@ -6,17 +6,17 @@ array_width = 100
 attr_fn_like_width = 100
 fn_call_width = 100
 
-format_code_in_doc_comments = true
+format_code_in_doc_comments = false
 fn_single_line = true
 format_macro_matchers = true
-format_macro_bodues = true
+format_macro_bodies = true
 format_strings = true
 merge_derives = false
 overflow_delimited_expr = true
 reorder_modules = false
 use_field_init_shorthand = true
 use_try_shorthand = true
-wrap_comments = true
+wrap_comments = false
 where_single_line = true
 unstable_features = true
 empty_item_single_line = true
diff --git a/src/lib.rs b/src/lib.rs
index 80572b3..a66a974 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -777,7 +777,8 @@ pub fn derive_wrapper(input: TokenStream) -> TokenStream {
 /// * `amplify::WrapperMut`
 /// * [`AsMut`]
 /// * [`core::borrow::BorrowMut`]
-/// You may skip `AsMut` and `BorrowMut` implementations with `#[wrapper_mut(NoRefs)]`.
+/// You may skip `AsMut` and `BorrowMut` implementations with
+/// `#[wrapper_mut(NoRefs)]`.
 ///
 /// You can implement additional derives, it they are implemented for the
 /// wrapped type, using `#[wrapper()]` proc macro:
diff --git a/src/wrapper.rs b/src/wrapper.rs
index 5c642c2..a25e18c 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -126,13 +126,9 @@ impl FromPath for Wrapper {
     const DERIVE: &'static str = "Wrapper";
     const NO_REFS: Self = Self::NoRefs;
 
-    fn default_set() -> Vec<Self> {
-        vec![Wrapper::AsRef, Wrapper::Borrow]
-    }
+    fn default_set() -> Vec<Self> { vec![Wrapper::AsRef, Wrapper::Borrow] }
 
-    fn is_not_ref(&self) -> bool {
-        *self != Wrapper::AsRef && *self != Wrapper::Borrow
-    }
+    fn is_not_ref(&self) -> bool { *self != Wrapper::AsRef && *self != Wrapper::Borrow }
 
     fn from_path(path: &Path) -> Result<Option<Self>> {
         path.segments.first().map_or(
@@ -640,14 +636,14 @@ impl Wrapper {
                     }
                 }
             },
-            Wrapper::NoRefs
-            | Wrapper::Hex
-            | Wrapper::Exp
-            | Wrapper::NumberFmt
-            | Wrapper::RangeOps
-            | Wrapper::MathOps
-            | Wrapper::BoolOps
-            | Wrapper::BitOps => unreachable!(),
+            Wrapper::NoRefs |
+            Wrapper::Hex |
+            Wrapper::Exp |
+            Wrapper::NumberFmt |
+            Wrapper::RangeOps |
+            Wrapper::MathOps |
+            Wrapper::BoolOps |
+            Wrapper::BitOps => unreachable!(),
         }
     }
 }
@@ -657,13 +653,9 @@ impl FromPath for WrapperMut {
     const DERIVE: &'static str = "WrapperMut";
     const NO_REFS: Self = Self::NoRefs;
 
-    fn default_set() -> Vec<Self> {
-        vec![WrapperMut::AsMut, WrapperMut::BorrowMut]
-    }
+    fn default_set() -> Vec<Self> { vec![WrapperMut::AsMut, WrapperMut::BorrowMut] }
 
-    fn is_not_ref(&self) -> bool {
-        *self != WrapperMut::AsMut && *self != WrapperMut::BorrowMut
-    }
+    fn is_not_ref(&self) -> bool { *self != WrapperMut::AsMut && *self != WrapperMut::BorrowMut }
 
     fn from_path(path: &Path) -> Result<Option<Self>> {
         path.segments.first().map_or(
@@ -990,11 +982,11 @@ impl WrapperMut {
                     }
                 }
             },
-            WrapperMut::NoRefs
-            | WrapperMut::RangeMut
-            | WrapperMut::MathAssign
-            | WrapperMut::BoolAssign
-            | WrapperMut::BitAssign => unreachable!(),
+            WrapperMut::NoRefs |
+            WrapperMut::RangeMut |
+            WrapperMut::MathAssign |
+            WrapperMut::BoolAssign |
+            WrapperMut::BitAssign => unreachable!(),
         }
     }
 }
diff --git a/syn/src/attr.rs b/syn/src/attr.rs
index b4214e0..9c6bc76 100644
--- a/syn/src/attr.rs
+++ b/syn/src/attr.rs
@@ -626,8 +626,8 @@ impl ParametrizedAttr {
     ///    [`AttrReq::path_req`], [`AttrReq::integer_req`],
     ///    [`AttrReq::float_req`], [`AttrReq::char_req`],
     ///    [`AttrReq::bytes_req`], [`AttrReq::string_req`] correspondingly.
-    /// 2. [`ParametrizedAttr::paths`] values
-    ///    matching ones specified in [`AttrReq::arg_req`] with values set to
+    /// 2. [`ParametrizedAttr::paths`] values matching ones specified in
+    ///    [`AttrReq::arg_req`] with values set to
     ///    [`crate::ListReq::Predefined::default`] are moved into
     ///    [`ParametrizedAttr::args`] field.
     pub fn check(&mut self, req: AttrReq) -> Result<(), Error> {

From 49d60335cced7b229dbb572ed33c08f7f0ccbbcd Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 16:56:22 +0200
Subject: [PATCH 12/13] wrapper: use new Inner APIs

---
 Cargo.toml     |  2 +-
 src/lib.rs     |  6 +-----
 src/wrapper.rs | 29 ++++++++++++++++-------------
 3 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 82166f0..0af4170 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,7 +28,7 @@ proc-macro2 = "1"
 amplify_syn = { version = "2.0.1", path = "syn" }
 
 [dev-dependencies]
-amplify = { version = "4.0.0" }
+amplify = { version = "4.4.0", git = "https://github.com/rust-amplify/rust-amplify", branch = "wrapper" }
 
 [target.'cfg(target_arch = "wasm32")'.dev-dependencies]
 wasm-bindgen-test = "0.3"
diff --git a/src/lib.rs b/src/lib.rs
index a66a974..5519171 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -720,7 +720,6 @@ pub fn derive_getters(input: TokenStream) -> TokenStream {
 /// Simple wrapper:
 /// ```
 /// # #[macro_use] extern crate amplify_derive;
-/// use amplify::Wrapper;
 ///
 /// #[derive(Wrapper, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, From, Debug, Display)]
 /// #[display(inner)]
@@ -734,10 +733,9 @@ pub fn derive_getters(input: TokenStream) -> TokenStream {
 /// # #[macro_use] extern crate amplify_derive;
 /// # use std::collections::HashMap;
 /// # use std::fmt::Debug;
+/// use amplify::Inner;
 /// use std::marker::PhantomData;
 ///
-/// use amplify::Wrapper;
-///
 /// #[derive(Clone, Wrapper, Default, From)]
 /// #[wrapper(Debug)]
 /// struct Wrapped<T, U>(
@@ -755,7 +753,6 @@ pub fn derive_getters(input: TokenStream) -> TokenStream {
 /// Wrappers for indexable types
 /// ```
 /// # #[macro_use] extern crate amplify_derive;
-/// use amplify::Wrapper;
 ///
 /// #[derive(Wrapper, From)]
 /// #[wrapper(Index, RangeOps)]
@@ -830,7 +827,6 @@ pub fn derive_wrapper(input: TokenStream) -> TokenStream {
 ///
 /// ```
 /// # #[macro_use] extern crate amplify_derive;
-/// use amplify::{Wrapper, WrapperMut};
 ///
 /// #[derive(
 ///     Wrapper, WrapperMut, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, From, Debug,
diff --git a/src/wrapper.rs b/src/wrapper.rs
index a25e18c..46d8adf 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -247,7 +247,7 @@ impl Wrapper {
                 #[automatically_derived]
                 impl #impl_generics ::core::str::FromStr for #ident_name #ty_generics #where_clause
                 {
-                    type Err = <<Self as #amplify_crate::Wrapper>::Inner as ::core::str::FromStr>::Err;
+                    type Err = <<Self as #amplify_crate::Inner>::Inner as ::core::str::FromStr>::Err;
 
                     #[inline]
                     fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -758,9 +758,9 @@ impl WrapperMut {
             },
             WrapperMut::AsMut => quote! {
                 #[automatically_derived]
-                impl #impl_generics ::core::convert::AsMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                impl #impl_generics ::core::convert::AsMut<<#ident_name #impl_generics as #amplify_crate::Inner>::Inner> for #ident_name #ty_generics #where_clause {
                     #[inline]
-                    fn as_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
+                    fn as_mut(&mut self) -> &mut <Self as #amplify_crate::Inner>::Inner {
                         &mut self.#field
                     }
                 }
@@ -777,9 +777,9 @@ impl WrapperMut {
             },
             WrapperMut::BorrowMut => quote! {
                 #[automatically_derived]
-                impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
+                impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Inner>::Inner> for #ident_name #ty_generics #where_clause {
                     #[inline]
-                    fn borrow_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
+                    fn borrow_mut(&mut self) -> &mut <Self as #amplify_crate::Inner>::Inner {
                         &mut self.#field
                     }
                 }
@@ -1005,14 +1005,9 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
 
     Ok(quote! {
         #[automatically_derived]
-        impl #impl_generics #amplify_crate::Wrapper for #ident_name #ty_generics #where_clause {
+        impl #impl_generics #amplify_crate::Inner for #ident_name #ty_generics #where_clause {
             type Inner = #from;
 
-            #[inline]
-            fn from_inner(inner: Self::Inner) -> Self {
-                Self::from(inner)
-            }
-
             #[inline]
             fn as_inner(&self) -> &Self::Inner {
                 &self.#field
@@ -1024,6 +1019,14 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
             }
         }
 
+        #[automatically_derived]
+        impl #impl_generics #amplify_crate::FromInner for #ident_name #ty_generics #where_clause {
+            #[inline]
+            fn from_inner(inner: Self::Inner) -> Self {
+                Self::from(inner)
+            }
+        }
+
         #[automatically_derived]
         impl #impl_generics ::core::convert::From<#ident_name #ty_generics> for #from #where_clause {
             #[inline]
@@ -1050,9 +1053,9 @@ pub(crate) fn inner_mut(input: DeriveInput) -> Result<TokenStream2> {
 
     Ok(quote! {
         #[automatically_derived]
-        impl #impl_generics #amplify_crate::WrapperMut for #ident_name #ty_generics #where_clause {
+        impl #impl_generics #amplify_crate::InnerMut for #ident_name #ty_generics #where_clause {
             #[inline]
-            fn as_inner_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
+            fn as_inner_mut(&mut self) -> &mut <Self as #amplify_crate::Inner>::Inner {
                 &mut self.#field
             }
         }

From 2b4c4ca08732037e094d1ca36b1140c78a682d1e Mon Sep 17 00:00:00 2001
From: Dr Maxim Orlovsky <orlovsky@ubideco.org>
Date: Sun, 8 Oct 2023 17:02:01 +0200
Subject: [PATCH 13/13] wrapper: allow to skip From and InnerFrom
 implementation

---
 Cargo.lock     |  3 +--
 src/lib.rs     |  6 +++---
 src/wrapper.rs | 32 ++++++++++++++++++++++----------
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 3804f8e..d8d769c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5,8 +5,7 @@ version = 3
 [[package]]
 name = "amplify"
 version = "4.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "213783efd41ed08b2861e86dd5aac633cf612f861e9222ace8b3621bd58af5c6"
+source = "git+https://github.com/rust-amplify/rust-amplify?branch=wrapper#4b419b6b996c454c45575b372a3393057f9fb8fc"
 dependencies = [
  "amplify_derive 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "amplify_num",
diff --git a/src/lib.rs b/src/lib.rs
index 5519171..b342f76 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -750,12 +750,12 @@ pub fn derive_getters(input: TokenStream) -> TokenStream {
 /// assert_eq!(w.into_inner(), HashMap::<usize, Vec<u8>>::default());
 /// ```
 ///
-/// Wrappers for indexable types
+/// Wrappers for indexable types, which do not allow explicit construction using `From` converters:
 /// ```
 /// # #[macro_use] extern crate amplify_derive;
 ///
-/// #[derive(Wrapper, From)]
-/// #[wrapper(Index, RangeOps)]
+/// #[derive(Wrapper)]
+/// #[wrapper(NoFrom, Index, RangeOps)]
 /// struct VecNewtype(Vec<u8>);
 /// ```
 #[proc_macro_derive(Wrapper, attributes(wrap, wrapper, amplify_crate))]
diff --git a/src/wrapper.rs b/src/wrapper.rs
index 46d8adf..e024349 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -27,6 +27,8 @@ const EXAMPLE: &str = r#"#[wrapper(LowerHex, Add)]"#;
 #[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
 enum Wrapper {
     NoRefs,
+    NoFrom,
+    From,
     // Formatting
     FromStr,
     Display,
@@ -126,7 +128,7 @@ impl FromPath for Wrapper {
     const DERIVE: &'static str = "Wrapper";
     const NO_REFS: Self = Self::NoRefs;
 
-    fn default_set() -> Vec<Self> { vec![Wrapper::AsRef, Wrapper::Borrow] }
+    fn default_set() -> Vec<Self> { vec![Wrapper::From, Wrapper::AsRef, Wrapper::Borrow] }
 
     fn is_not_ref(&self) -> bool { *self != Wrapper::AsRef && *self != Wrapper::Borrow }
 
@@ -135,6 +137,8 @@ impl FromPath for Wrapper {
             Err(attr_err!(path.span(), NAME, "must contain at least one identifier", EXAMPLE)),
             |segment| {
                 Ok(match segment.ident.to_string().as_str() {
+                    "From" => Some(Wrapper::From),
+                    "NoFrom" => Some(Wrapper::NoFrom),
                     "FromStr" => Some(Wrapper::FromStr),
                     "Display" => Some(Wrapper::Display),
                     "Debug" => Some(Wrapper::Debug),
@@ -243,6 +247,15 @@ impl Wrapper {
         let amplify_crate = get_amplify_crate(input);
 
         match self {
+            Wrapper::From => quote! {
+                #[automatically_derived]
+                impl #impl_generics #amplify_crate::FromInner for #ident_name #ty_generics #where_clause {
+                    #[inline]
+                    fn from_inner(inner: Self::Inner) -> Self {
+                        Self::from(inner)
+                    }
+                }
+            },
             Wrapper::FromStr => quote! {
                 #[automatically_derived]
                 impl #impl_generics ::core::str::FromStr for #ident_name #ty_generics #where_clause
@@ -637,6 +650,7 @@ impl Wrapper {
                 }
             },
             Wrapper::NoRefs |
+            Wrapper::NoFrom |
             Wrapper::Hex |
             Wrapper::Exp |
             Wrapper::NumberFmt |
@@ -998,7 +1012,13 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
 
     let (field, from) = get_params(&input)?;
 
-    let wrappers = get_wrappers::<Wrapper>(&input)?;
+    let mut wrappers = get_wrappers::<Wrapper>(&input)?;
+    if wrappers.contains(&Wrapper::NoFrom) {
+        wrappers = wrappers
+            .into_iter()
+            .filter(|w| *w != Wrapper::From && *w != Wrapper::NoFrom)
+            .collect();
+    }
     let wrapper_derive = wrappers
         .iter()
         .map(|w| w.into_token_stream2(&input, &from, &field));
@@ -1019,14 +1039,6 @@ pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
             }
         }
 
-        #[automatically_derived]
-        impl #impl_generics #amplify_crate::FromInner for #ident_name #ty_generics #where_clause {
-            #[inline]
-            fn from_inner(inner: Self::Inner) -> Self {
-                Self::from(inner)
-            }
-        }
-
         #[automatically_derived]
         impl #impl_generics ::core::convert::From<#ident_name #ty_generics> for #from #where_clause {
             #[inline]