Skip to content

Commit

Permalink
feat(dyn-abi): implement more ext traits for json-abi (#243)
Browse files Browse the repository at this point in the history
* feat(dyn-abi): implement more ext traits for json-abi

* fixes

* docs

* fix

* dedup code

* chore
  • Loading branch information
DaniPopes authored Aug 30, 2023
1 parent 5f12652 commit c06e690
Show file tree
Hide file tree
Showing 13 changed files with 523 additions and 373 deletions.
84 changes: 40 additions & 44 deletions crates/dyn-abi/src/eip712/coerce.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{DynAbiError, DynAbiResult, DynSolType, DynSolValue, Word};
use crate::{DynSolType, DynSolValue, Error, Result, Word};
use alloc::{
boxed::Box,
string::{String, ToString},
Expand All @@ -8,7 +8,7 @@ use alloy_primitives::{Address, Function, I256, U256};

impl DynSolType {
/// Coerce a [`serde_json::Value`] to a [`DynSolValue`] via this type.
pub fn coerce(&self, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
pub fn coerce(&self, value: &serde_json::Value) -> Result<DynSolValue> {
match self {
Self::Address => address(value),
Self::Function => function(value),
Expand All @@ -30,31 +30,31 @@ impl DynSolType {
}
}

fn address(value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn address(value: &serde_json::Value) -> Result<DynSolValue> {
let address = value
.as_str()
.map(|s| {
s.parse::<Address>()
.map_err(|_| DynAbiError::type_mismatch(DynSolType::Address, value))
.map_err(|_| Error::type_mismatch(&DynSolType::Address, value))
})
.ok_or_else(|| DynAbiError::type_mismatch(DynSolType::Address, value))??;
.ok_or_else(|| Error::type_mismatch(&DynSolType::Address, value))??;

Ok(DynSolValue::Address(address))
}

fn function(value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn function(value: &serde_json::Value) -> Result<DynSolValue> {
let function = value
.as_str()
.map(|s| {
s.parse::<Function>()
.map_err(|_| DynAbiError::type_mismatch(DynSolType::Function, value))
.map_err(|_| Error::type_mismatch(&DynSolType::Function, value))
})
.ok_or_else(|| DynAbiError::type_mismatch(DynSolType::Function, value))??;
.ok_or_else(|| Error::type_mismatch(&DynSolType::Function, value))??;

Ok(DynSolValue::Function(function))
}

fn bool(value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn bool(value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(bool) = value.as_bool() {
return Ok(DynSolValue::Bool(bool))
}
Expand All @@ -63,13 +63,13 @@ fn bool(value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
.as_str()
.map(|s| {
s.parse::<bool>()
.map_err(|_| DynAbiError::type_mismatch(DynSolType::Address, value))
.map_err(|_| Error::type_mismatch(&DynSolType::Address, value))
})
.ok_or_else(|| DynAbiError::type_mismatch(DynSolType::Address, value))??;
.ok_or_else(|| Error::type_mismatch(&DynSolType::Address, value))??;
Ok(DynSolValue::Bool(bool))
}

fn int(n: usize, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn int(n: usize, value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(num) = value.as_i64() {
return Ok(DynSolValue::Int(I256::try_from(num).unwrap(), n))
}
Expand All @@ -78,10 +78,10 @@ fn int(n: usize, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
return Ok(DynSolValue::Int(i, n))
}

Err(DynAbiError::type_mismatch(DynSolType::Int(n), value))
Err(Error::type_mismatch(&DynSolType::Int(n), value))
}

fn uint(n: usize, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn uint(n: usize, value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(num) = value.as_u64() {
return Ok(DynSolValue::Uint(U256::from(num), n))
}
Expand All @@ -96,41 +96,41 @@ fn uint(n: usize, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
}
}

Err(DynAbiError::type_mismatch(DynSolType::Uint(n), value))
Err(Error::type_mismatch(&DynSolType::Uint(n), value))
}

fn fixed_bytes(n: usize, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn fixed_bytes(n: usize, value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(Ok(buf)) = value.as_str().map(hex::decode) {
let mut word: Word = Default::default();
let min = n.min(buf.len());
word[..min].copy_from_slice(&buf[..min]);
return Ok(DynSolValue::FixedBytes(word, n))
}

Err(DynAbiError::type_mismatch(DynSolType::FixedBytes(n), value))
Err(Error::type_mismatch(&DynSolType::FixedBytes(n), value))
}

fn string(value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn string(value: &serde_json::Value) -> Result<DynSolValue> {
let string = value
.as_str()
.map(|s| s.to_string())
.ok_or_else(|| DynAbiError::type_mismatch(DynSolType::String, value))?;
.ok_or_else(|| Error::type_mismatch(&DynSolType::String, value))?;
Ok(DynSolValue::String(string))
}

fn bytes(value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn bytes(value: &serde_json::Value) -> Result<DynSolValue> {
let bytes = value
.as_str()
.map(|s| hex::decode(s).map_err(|_| DynAbiError::type_mismatch(DynSolType::Bytes, value)))
.ok_or_else(|| DynAbiError::type_mismatch(DynSolType::Bytes, value))??;
.map(|s| hex::decode(s).map_err(|_| Error::type_mismatch(&DynSolType::Bytes, value)))
.ok_or_else(|| Error::type_mismatch(&DynSolType::Bytes, value))??;
Ok(DynSolValue::Bytes(bytes))
}

fn tuple(inner: &[DynSolType], value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn tuple(inner: &[DynSolType], value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(arr) = value.as_array() {
if inner.len() != arr.len() {
return Err(DynAbiError::type_mismatch(
DynSolType::Tuple(inner.to_vec()),
return Err(Error::type_mismatch(
&DynSolType::Tuple(inner.to_vec()),
value,
))
}
Expand All @@ -144,13 +144,13 @@ fn tuple(inner: &[DynSolType], value: &serde_json::Value) -> DynAbiResult<DynSol
return Ok(DynSolValue::Tuple(tuple))
}

Err(DynAbiError::type_mismatch(
DynSolType::Tuple(inner.to_vec()),
Err(Error::type_mismatch(
&DynSolType::Tuple(inner.to_vec()),
value,
))
}

fn array(inner: &DynSolType, value: &serde_json::Value) -> DynAbiResult<DynSolValue> {
fn array(inner: &DynSolType, value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(arr) = value.as_array() {
let array = arr
.iter()
Expand All @@ -160,21 +160,17 @@ fn array(inner: &DynSolType, value: &serde_json::Value) -> DynAbiResult<DynSolVa
return Ok(DynSolValue::Array(array))
}

Err(DynAbiError::type_mismatch(
DynSolType::Array(Box::new(inner.clone())),
Err(Error::type_mismatch(
&DynSolType::Array(Box::new(inner.clone())),
value,
))
}

fn fixed_array(
inner: &DynSolType,
n: usize,
value: &serde_json::Value,
) -> DynAbiResult<DynSolValue> {
fn fixed_array(inner: &DynSolType, n: usize, value: &serde_json::Value) -> Result<DynSolValue> {
if let Some(arr) = value.as_array() {
if arr.len() != n {
return Err(DynAbiError::type_mismatch(
DynSolType::FixedArray(Box::new(inner.clone()), n),
return Err(Error::type_mismatch(
&DynSolType::FixedArray(Box::new(inner.clone()), n),
value,
))
}
Expand All @@ -187,8 +183,8 @@ fn fixed_array(
return Ok(DynSolValue::FixedArray(array))
}

Err(DynAbiError::type_mismatch(
DynSolType::FixedArray(Box::new(inner.clone()), n),
Err(Error::type_mismatch(
&DynSolType::FixedArray(Box::new(inner.clone()), n),
value,
))
}
Expand All @@ -198,15 +194,15 @@ pub(crate) fn coerce_custom_struct(
prop_names: &[String],
inner: &[DynSolType],
value: &serde_json::Value,
) -> Result<DynSolValue, DynAbiError> {
) -> Result<DynSolValue> {
if let Some(map) = value.as_object() {
let mut tuple = vec![];
for (name, ty) in prop_names.iter().zip(inner.iter()) {
if let Some(v) = map.get(name) {
tuple.push(ty.coerce(v)?);
} else {
return Err(DynAbiError::type_mismatch(
DynSolType::CustomStruct {
return Err(Error::type_mismatch(
&DynSolType::CustomStruct {
name: name.to_string(),
prop_names: prop_names.to_vec(),
tuple: inner.to_vec(),
Expand All @@ -222,8 +218,8 @@ pub(crate) fn coerce_custom_struct(
})
}

Err(DynAbiError::type_mismatch(
DynSolType::CustomStruct {
Err(Error::type_mismatch(
&DynSolType::CustomStruct {
name: name.to_string(),
prop_names: prop_names.to_vec(),
tuple: inner.to_vec(),
Expand Down
16 changes: 8 additions & 8 deletions crates/dyn-abi/src/eip712/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
eip712::resolver::{PropertyDef, TypeDef},
DynAbiError,
Error,
};
use alloc::vec::Vec;
use alloy_sol_type_parser::{Error as TypeParserError, TypeSpecifier};
Expand All @@ -25,12 +25,12 @@ impl PropDef<'_> {
}

impl<'a> TryFrom<&'a str> for PropDef<'a> {
type Error = DynAbiError;
type Error = Error;

fn try_from(input: &'a str) -> Result<Self, Self::Error> {
let (ty, name) = input
.rsplit_once(' ')
.ok_or_else(|| DynAbiError::invalid_property_def(input))?;
.ok_or_else(|| Error::invalid_property_def(input))?;
Ok(PropDef {
ty: ty.trim().try_into()?,
name: name.trim(),
Expand Down Expand Up @@ -64,12 +64,12 @@ impl ComponentType<'_> {

// This impl handles
impl<'a> TryFrom<&'a str> for ComponentType<'a> {
type Error = DynAbiError;
type Error = Error;

fn try_from(input: &'a str) -> Result<Self, Self::Error> {
let (name, props_str) = input.split_once('(').ok_or_else(|| {
DynAbiError::TypeParserError(TypeParserError::invalid_type_string(input))
})?;
let (name, props_str) = input
.split_once('(')
.ok_or_else(|| Error::TypeParser(TypeParserError::invalid_type_string(input)))?;

let mut props = vec![];
let mut depth = 1; // 1 to account for the ( in the split above
Expand Down Expand Up @@ -112,7 +112,7 @@ pub struct EncodeType<'a> {
}

impl<'a> TryFrom<&'a str> for EncodeType<'a> {
type Error = DynAbiError;
type Error = Error;

fn try_from(input: &'a str) -> Result<Self, Self::Error> {
let mut types = vec![];
Expand Down
Loading

0 comments on commit c06e690

Please sign in to comment.