Skip to content

Commit

Permalink
feat(sol-types): introduce SolValue, make Encodable an impl detail (
Browse files Browse the repository at this point in the history
#333)

* feat(sol-types): make Encodable actually work

* add more impls to both encodables

* chore: clippy

* fixtest

* fixstable

* tuple perfington

* cleanup

* from

* officially make SolTypeEncodable an implementation detail

* docs

* impl Encodable for sol! SolTypes

* update examples

* rename to SolValue

* update docs

* rename value module

* rename SolTypeEncodable to SolTypeValue

* rename SolTypeValue methods to avoid naming collisions

* update event doc

* tweaks

* final tweaks
  • Loading branch information
DaniPopes authored Oct 7, 2023
1 parent aaaaa10 commit 88ef37f
Show file tree
Hide file tree
Showing 31 changed files with 1,226 additions and 660 deletions.
9 changes: 5 additions & 4 deletions .github/ISSUE_TEMPLATE/BUG-FORM.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ body:
description: What component is the bug in?
multiple: true
options:
- primitives
- syn-solidity
- sol-type
- sol! macro
- dyn-abi
- json-abi
- primitives
- sol-type-parser
- sol-types
- sol! macro
- syn-solidity
- Other (please provide more details)
validations:
required: true
Expand Down
61 changes: 32 additions & 29 deletions .github/ISSUE_TEMPLATE/FEATURE-FORM.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,35 @@ description: Suggest a feature
labels: ["enhancement"]
title: "[Feature] "
body:
- type: markdown
attributes:
value: |
Please ensure that the feature has not already been requested in the issue tracker.
- type: dropdown
attributes:
label: Component
description: What component is the feature for?
multiple: true
options:
- primitives
- syn-solidity
- sol-type
- sol! macro
- dyn-abi
- json-abi
- Other (please provide more details)
validations:
required: true
- type: textarea
attributes:
label: Describe the feature you would like
description: Please also describe your goals for the feature. What problems it solves, how it would be used, etc.
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context to the feature (like screenshots, resources)
- type: markdown
attributes:
value: |
Please ensure that the feature has not already been requested in the issue tracker.
- type: dropdown
attributes:
label: Component
description: What component is the feature for?
multiple: true
options:
- dyn-abi
- json-abi
- primitives
- sol-type-parser
- sol-types
- sol! macro
- syn-solidity
- Other (please provide more details)
validations:
required: true
- type: textarea
attributes:
label: Describe the feature you would like
description:
Please also describe your goals for the feature. What problems it solves, how it would
be used, etc.
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context to the feature (like screenshots, resources)
1 change: 0 additions & 1 deletion crates/dyn-abi/src/ext/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use sealed::Sealed;
///
/// This trait is sealed and cannot be implemented for types outside of this
/// crate. It is implemented only for the following types:
///
/// - [`Constructor`]
/// - [`Error`]
/// - [`Function`]
Expand Down
4 changes: 2 additions & 2 deletions crates/dyn-abi/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ fn tuple<T: ResolveSolType>(slice: &[T]) -> Result<Vec<DynSolType>> {
Ok(types)
}

macro_rules! deref_impl {
macro_rules! deref_impls {
($($(#[$attr:meta])* [$($gen:tt)*] $t:ty),+ $(,)?) => {$(
$(#[$attr])*
impl<$($gen)*> ResolveSolType for $t {
Expand All @@ -231,7 +231,7 @@ macro_rules! deref_impl {
)+};
}

deref_impl! {
deref_impls! {
[] alloc::string::String,
[T: ?Sized + ResolveSolType] &T,
[T: ?Sized + ResolveSolType] &mut T,
Expand Down
33 changes: 18 additions & 15 deletions crates/sol-macro/src/expand/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,26 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, enumm: &ItemEnum) -> Result<TokenStream>
}

#[automatically_derived]
impl ::alloy_sol_types::Encodable<#name> for #name {
impl ::alloy_sol_types::SolValue for #name {
type SolType = Self;
}

#[automatically_derived]
impl ::alloy_sol_types::private::SolTypeValue<#name> for #name {
#[inline]
fn to_tokens(&self) -> #uint8_st::TokenType<'_> {
fn stv_to_tokens(&self) -> #uint8_st::TokenType<'_> {
::alloy_sol_types::Word::with_last_byte(*self as u8).into()
}

#[inline]
fn stv_eip712_data_word(&self) -> ::alloy_sol_types::Word {
#uint8_st::eip712_data_word(self.as_u8())
}

#[inline]
fn stv_abi_encode_packed_to(&self, out: &mut ::alloy_sol_types::private::Vec<u8>) {
out.push(*self as u8);
}
}

#[automatically_derived]
Expand Down Expand Up @@ -150,16 +165,6 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, enumm: &ItemEnum) -> Result<TokenStream>
#uint8_st::detokenize(token)
).#detokenize_unwrap
}

#[inline]
fn eip712_data_word(rust: &Self::RustType) -> ::alloy_sol_types::Word {
#uint8_st::eip712_data_word(rust.as_u8())
}

#[inline]
fn abi_encode_packed_to(rust: &Self::RustType, out: &mut ::alloy_sol_types::private::Vec<u8>) {
out.push(*rust as u8);
}
}

#[automatically_derived]
Expand All @@ -175,9 +180,7 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, enumm: &ItemEnum) -> Result<TokenStream>
}

#[inline]
fn encode_topic(
rust: &Self::RustType
) -> ::alloy_sol_types::abi::token::WordToken {
fn encode_topic(rust: &Self::RustType) -> ::alloy_sol_types::abi::token::WordToken {
<#uint8 as ::alloy_sol_types::EventTopic>::encode_topic(rust.as_u8())
}
}
Expand Down
13 changes: 0 additions & 13 deletions crates/sol-macro/src/expand/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,6 @@ fn expand_from_into_tuples<P>(name: &Ident, fields: &Parameters<P>) -> TokenStre
let names2 = names.clone();
let idxs = (0..fields.len()).map(syn::Index::from);

let names3 = names.clone();
let field_tys = fields.types().map(expand_type);

let (sol_tuple, rust_tuple) = expand_tuple_types(fields.types());

quote! {
Expand All @@ -574,16 +571,6 @@ fn expand_from_into_tuples<P>(name: &Ident, fields: &Parameters<P>) -> TokenStre
}
}
}

#[automatically_derived]
#[doc(hidden)]
impl ::alloy_sol_types::Encodable<UnderlyingSolTuple<'_>> for #name {
fn to_tokens(&self) -> <UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::TokenType<'_> {
(#(
::alloy_sol_types::Encodable::<#field_tys>::to_tokens(&self.#names3),
)*)
}
}
}
}

Expand Down
51 changes: 27 additions & 24 deletions crates/sol-macro/src/expand/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,34 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, s: &ItemStruct) -> Result<TokenStream> {
#convert

#[automatically_derived]
impl ::alloy_sol_types::Encodable<Self> for #name {
fn to_tokens(&self) -> <Self as ::alloy_sol_types::SolType>::TokenType<'_> {
impl ::alloy_sol_types::SolValue for #name {
type SolType = Self;
}

#[automatically_derived]
impl ::alloy_sol_types::private::SolTypeValue<Self> for #name {
fn stv_to_tokens(&self) -> <Self as ::alloy_sol_types::SolType>::TokenType<'_> {
#tokenize_impl
}

#[inline]
fn stv_abi_encoded_size(&self) -> usize {
// TODO: Avoid cloning
let tuple = <UnderlyingRustTuple<'_> as ::core::convert::From<Self>>::from(self.clone());
<UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::abi_encoded_size(&tuple)
}

#[inline]
fn stv_eip712_data_word(&self) -> ::alloy_sol_types::Word {
<Self as ::alloy_sol_types::SolStruct>::eip712_hash_struct(self)
}

#[inline]
fn stv_abi_encode_packed_to(&self, out: &mut ::alloy_sol_types::private::Vec<u8>) {
// TODO: Avoid cloning
let tuple = <UnderlyingRustTuple<'_> as ::core::convert::From<Self>>::from(self.clone());
<UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::abi_encode_packed_to(&tuple, out)
}
}

#[automatically_derived]
Expand All @@ -95,13 +119,6 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, s: &ItemStruct) -> Result<TokenStream> {
)
}

#[inline]
fn abi_encoded_size(rust: &Self::RustType) -> usize {
// TODO: Avoid cloning
let tuple = <UnderlyingRustTuple<'_> as ::core::convert::From<Self>>::from(rust.clone());
<UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::abi_encoded_size(&tuple)
}

#[inline]
fn valid_token(token: &Self::TokenType<'_>) -> bool {
<UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::valid_token(token)
Expand All @@ -112,18 +129,6 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, s: &ItemStruct) -> Result<TokenStream> {
let tuple = <UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::detokenize(token);
<Self as ::core::convert::From<UnderlyingRustTuple<'_>>>::from(tuple)
}

#[inline]
fn eip712_data_word(rust: &Self::RustType) -> ::alloy_sol_types::Word {
<Self as ::alloy_sol_types::SolStruct>::eip712_hash_struct(rust)
}

#[inline]
fn abi_encode_packed_to(rust: &Self::RustType, out: &mut ::alloy_sol_types::private::Vec<u8>) {
// TODO: Avoid cloning
let tuple = <UnderlyingRustTuple<'_> as ::core::convert::From<Self>>::from(rust.clone());
<UnderlyingSolTuple<'_> as ::alloy_sol_types::SolType>::abi_encode_packed_to(&tuple, out)
}
}

#[automatically_derived]
Expand Down Expand Up @@ -156,9 +161,7 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, s: &ItemStruct) -> Result<TokenStream> {
}

#[inline]
fn encode_topic(
rust: &Self::RustType
) -> ::alloy_sol_types::abi::token::WordToken {
fn encode_topic(rust: &Self::RustType) -> ::alloy_sol_types::abi::token::WordToken {
let mut out = ::alloy_sol_types::private::Vec::new();
<Self as ::alloy_sol_types::EventTopic>::encode_topic_preimage(rust, &mut out);
::alloy_sol_types::abi::token::WordToken(
Expand Down
26 changes: 16 additions & 10 deletions crates/sol-types/src/abi/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,13 @@ impl<'de> Decoder<'de> {
}
}

/// ABI-decodes a single token by wrapping it in a single-element tuple.
/// ABI-decodes a token by wrapping it in a single-element tuple.
///
/// You should probably be using
/// [`SolType::abi_decode`](crate::SolType::abi_decode) if you're not intending
/// to use raw tokens.
/// You are probably looking for
/// [`SolValue::abi_decode`](crate::SolValue::abi_decode) if you are not
/// intending to use raw tokens.
///
/// See the [`abi`](super) module for more information.
#[inline]
pub fn decode<'de, T: TokenType<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
decode_sequence::<(T,)>(data, validate).map(|(t,)| t)
Expand All @@ -254,9 +256,11 @@ pub fn decode<'de, T: TokenType<'de>>(data: &'de [u8], validate: bool) -> Result
/// Decodes as function parameters if [`T` is a tuple](TokenSeq::IS_TUPLE).
/// Otherwise, decodes it as a single-element tuple.
///
/// You should probably be using
/// [`SolType::abi_decode_params`](crate::SolType::abi_decode_params) if you're
/// not intending to use raw tokens.
/// You are probably looking for
/// [`SolValue::abi_decode_params`](crate::SolValue::abi_decode_params) if
/// you are not intending to use raw tokens.
///
/// See the [`abi`](super) module for more information.
#[inline]
pub fn decode_params<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
if T::IS_TUPLE {
Expand All @@ -269,9 +273,11 @@ pub fn decode_params<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) ->
/// Decodes ABI compliant vector of bytes into vector of tokens described by
/// types param.
///
/// You should probably be using
/// [`SolType::abi_decode_sequence`](crate::SolType::abi_decode_sequence) if
/// you're not intending to use raw tokens.
/// You are probably looking for
/// [`SolValue::abi_decode_sequence`](crate::SolValue::abi_decode_sequence) if
/// you are not intending to use raw tokens.
///
/// See the [`abi`](super) module for more information.
pub fn decode_sequence<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
let mut decoder = Decoder::new(data, validate);
let res = decoder.decode_sequence::<T>()?;
Expand Down
Loading

0 comments on commit 88ef37f

Please sign in to comment.