Skip to content

Commit

Permalink
serde in no_std
Browse files Browse the repository at this point in the history
  • Loading branch information
kvinwang authored and vkgnosis committed Nov 15, 2022
1 parent 8501b69 commit 4b592af
Show file tree
Hide file tree
Showing 23 changed files with 139 additions and 111 deletions.
16 changes: 11 additions & 5 deletions ethabi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ edition = "2018"

[dependencies]
hex = { version = "0.4", default-features = false, features = ["alloc"] }
serde = { version = "1.0", optional = true, features = ["derive"] }
serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] }
serde_json = { version = "1.0", optional = true }
sha3 = { version = "0.10", default-features = false }
ethereum-types = { version = "0.13.1", default-features = false }
thiserror = { version = "1", optional = true }
uint = { version = "0.9.0", optional = true }
uint = { version = "0.9.0", default-features = false, optional = true }
regex = { version = "1.5.4", optional = true }
once_cell = { version = "1.9.0", optional = true }

[dev-dependencies]
hex-literal = "0.3"
paste = "1"
serde_json = "1.0"

[features]
default = [
Expand All @@ -38,16 +39,21 @@ std = [
"sha3/std",
"ethereum-types/std",
"thiserror",
"uint/std",
"uint?/std",
"serde?/std",
]

serde = [
"dep:serde",
"ethereum-types/serialize",
"uint",
]

# To enable custom `Reader`/`Tokenizer` and `serde` features support
full-serde = [
"std",
"serde",
"serde_json",
"uint",
"ethereum-types/serialize",
"regex",
"once_cell"
]
Expand Down
4 changes: 2 additions & 2 deletions ethabi/src/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

//! Contract constructor call builder.

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use crate::{encode, Bytes, Error, Param, ParamType, Result, Token};

/// Contract constructor specification.
#[cfg_attr(feature = "full-serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct Constructor {
/// Constructor input.
Expand Down
21 changes: 12 additions & 9 deletions ethabi/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
// except according to those terms.

use alloc::collections::{btree_map::Values, BTreeMap};
#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use core::fmt;
use core::iter::Flatten;
#[cfg(feature = "full-serde")]
use std::io;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeSeq,
Expand All @@ -22,7 +22,7 @@ use serde::{

#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use crate::operation::Operation;
use crate::{error::Error as AbiError, errors, Constructor, Error, Event, Function};

Expand All @@ -43,7 +43,7 @@ pub struct Contract {
pub fallback: bool,
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl<'a> Deserialize<'a> for Contract {
fn deserialize<D>(deserializer: D) -> Result<Contract, D::Error>
where
Expand All @@ -53,10 +53,10 @@ impl<'a> Deserialize<'a> for Contract {
}
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
struct ContractVisitor;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl<'a> Visitor<'a> for ContractVisitor {
type Value = Contract;

Expand Down Expand Up @@ -96,7 +96,7 @@ impl<'a> Visitor<'a> for ContractVisitor {
}
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl Serialize for Contract {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand Down Expand Up @@ -253,10 +253,13 @@ impl<'a> Iterator for AbiErrors<'a> {
}
}

#[cfg(all(test, feature = "full-serde"))]
#[cfg(all(test, feature = "serde"))]
#[allow(deprecated)]
mod test {
use std::{collections::BTreeMap, iter::FromIterator};
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use alloc::collections::BTreeMap;
use core::iter::FromIterator;

use crate::{tests::assert_ser_de, AbiError, Constructor, Contract, Event, EventParam, Function, Param, ParamType};

Expand Down
6 changes: 3 additions & 3 deletions ethabi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

//! Contract error

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "std"))]
Expand All @@ -20,11 +20,11 @@ use crate::{
};

/// Contract error specification.
#[cfg_attr(feature = "full-serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct Error {
/// Error name.
#[cfg_attr(feature = "full-serde", serde(deserialize_with = "crate::util::sanitize_name::deserialize"))]
#[cfg_attr(feature = "serde", serde(deserialize_with = "crate::util::sanitize_name::deserialize"))]
pub name: String,
/// Error input.
pub inputs: Vec<Param>,
Expand Down
16 changes: 8 additions & 8 deletions ethabi/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use crate::no_std_prelude::Cow;
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use core::num;
#[cfg(feature = "std")]
use thiserror::Error;
Expand All @@ -32,19 +32,19 @@ pub enum Error {
#[error("Serialization error: {0}")]
SerdeJson(#[from] serde_json::Error),
/// Integer parsing error.
#[cfg(feature = "full-serde")]
#[error("Integer parsing error: {0}")]
ParseInt(#[from] num::ParseIntError),
#[cfg(feature = "serde")]
#[cfg_attr(feature = "std", error("Integer parsing error: {0}"))]
ParseInt(#[cfg_attr(feature = "std", from)] num::ParseIntError),
/// Hex string parsing error.
#[cfg(feature = "full-serde")]
#[error("Hex parsing error: {0}")]
Hex(#[from] hex::FromHexError),
#[cfg(feature = "serde")]
#[cfg_attr(feature = "std", error("Hex parsing error: {0}"))]
Hex(#[cfg_attr(feature = "std", from)] hex::FromHexError),
/// Other errors.
#[cfg_attr(feature = "std", error("{0}"))]
Other(Cow<'static, str>),
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl From<uint::FromDecStrErr> for Error {
fn from(err: uint::FromDecStrErr) -> Self {
use uint::FromDecStrErr::*;
Expand Down
6 changes: 3 additions & 3 deletions ethabi/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use alloc::collections::BTreeMap;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use sha3::{Digest, Keccak256};

Expand All @@ -22,11 +22,11 @@ use crate::{
};

/// Contract event.
#[cfg_attr(feature = "full-serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Event {
/// Event name.
#[cfg_attr(feature = "full-serde", serde(deserialize_with = "crate::util::sanitize_name::deserialize"))]
#[cfg_attr(feature = "serde", serde(deserialize_with = "crate::util::sanitize_name::deserialize"))]
pub name: String,
/// Event input.
pub inputs: Vec<EventParam>,
Expand Down
18 changes: 10 additions & 8 deletions ethabi/src/event_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

//! Event param specification.

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use core::fmt;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{
de::{Error, MapAccess, Visitor},
ser::SerializeMap,
Expand All @@ -21,7 +21,7 @@ use serde::{
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use crate::ParamType;
#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use crate::{param_type::Writer, TupleParam};

/// Event param specification.
Expand All @@ -35,7 +35,7 @@ pub struct EventParam {
pub indexed: bool,
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl<'a> Deserialize<'a> for EventParam {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand All @@ -45,10 +45,10 @@ impl<'a> Deserialize<'a> for EventParam {
}
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
struct EventParamVisitor;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl<'a> Visitor<'a> for EventParamVisitor {
type Value = EventParam;

Expand Down Expand Up @@ -103,7 +103,7 @@ impl<'a> Visitor<'a> for EventParamVisitor {
}
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl Serialize for EventParam {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -121,8 +121,10 @@ impl Serialize for EventParam {
}
}

#[cfg(all(test, feature = "full-serde"))]
#[cfg(all(test, feature = "serde"))]
mod tests {
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use crate::{tests::assert_json_eq, EventParam, ParamType};

#[test]
Expand Down
30 changes: 12 additions & 18 deletions ethabi/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

use core::ops;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{Serialize, Serializer};
#[cfg(feature = "full-serde")]
use serde_json::Value;

#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
Expand Down Expand Up @@ -41,7 +39,7 @@ pub struct TopicFilter {
pub topic3: Topic<Hash>,
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl Serialize for TopicFilter {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand Down Expand Up @@ -121,21 +119,17 @@ impl<T> From<Topic<T>> for Vec<T> {
}
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
impl Serialize for Topic<Hash> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let value = match *self {
Topic::Any => Value::Null,
Topic::OneOf(ref vec) => {
let v = vec.iter().map(|h| format!("0x{h:x}")).map(Value::String).collect();
Value::Array(v)
}
Topic::This(ref hash) => Value::String(format!("0x{hash:x}")),
};
value.serialize(serializer)
match *self {
Topic::Any => Option::<()>::None.serialize(serializer),
Topic::OneOf(ref vec) => vec.serialize(serializer),
Topic::This(ref hash) => hash.serialize(serializer),
}
}
}

Expand All @@ -159,19 +153,19 @@ impl<T> ops::Index<usize> for Topic<T> {
#[cfg(test)]
mod tests {
use super::Topic;
#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use super::TopicFilter;
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use crate::Hash;

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
fn hash(s: &'static str) -> Hash {
s.parse().unwrap()
}

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
#[test]
fn test_topic_filter_serialization() {
let expected = r#"["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",null,["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b","0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc"],null]"#;
Expand Down
10 changes: 5 additions & 5 deletions ethabi/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

//! Contract function call builder.

#[cfg(feature = "full-serde")]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "std"))]
Expand All @@ -18,11 +18,11 @@ use crate::{
};

/// Contract function specification.
#[cfg_attr(feature = "full-serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct Function {
/// Function name.
#[cfg_attr(feature = "full-serde", serde(deserialize_with = "crate::util::sanitize_name::deserialize"))]
#[cfg_attr(feature = "serde", serde(deserialize_with = "crate::util::sanitize_name::deserialize"))]
pub name: String,
/// Function input.
pub inputs: Vec<Param>,
Expand All @@ -31,10 +31,10 @@ pub struct Function {
#[deprecated(note = "The constant attribute was removed in Solidity 0.5.0 and has been \
replaced with stateMutability.")]
/// Constant function.
#[cfg_attr(feature = "full-serde", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub constant: Option<bool>,
/// Whether the function reads or modifies blockchain state
#[cfg_attr(feature = "full-serde", serde(rename = "stateMutability", default))]
#[cfg_attr(feature = "serde", serde(rename = "stateMutability", default))]
pub state_mutability: StateMutability,
}

Expand Down
Loading

0 comments on commit 4b592af

Please sign in to comment.