use crate::types::{Address, Bytes, U256};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct CallRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub from: Option<Address>,
pub to: Address,
#[serde(skip_serializing_if = "Option::is_none")]
pub gas: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "gasPrice")]
pub gas_price: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Bytes>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TransactionRequest {
pub from: Address,
#[serde(skip_serializing_if = "Option::is_none")]
pub to: Option<Address>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gas: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "gasPrice")]
pub gas_price: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Bytes>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nonce: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<TransactionCondition>,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub enum TransactionCondition {
#[serde(rename = "block")]
Block(u64),
#[serde(rename = "time")]
Timestamp(u64),
}
#[cfg(test)]
mod tests {
use super::{Address, CallRequest, TransactionCondition, TransactionRequest};
use serde_json;
#[test]
fn should_serialize_call_request() {
let call_request = CallRequest {
from: None,
to: Address::from_low_u64_be(5),
gas: Some(21_000.into()),
gas_price: None,
value: Some(5_000_000.into()),
data: Some(vec![1, 2, 3].into()),
};
let serialized = serde_json::to_string_pretty(&call_request).unwrap();
assert_eq!(
serialized,
r#"{
"to": "0x0000000000000000000000000000000000000005",
"gas": "0x5208",
"value": "0x4c4b40",
"data": "0x010203"
}"#
);
}
#[test]
fn should_deserialize_call_request() {
let serialized = r#"{
"to": "0x0000000000000000000000000000000000000005",
"gas": "0x5208",
"value": "0x4c4b40",
"data": "0x010203"
}"#;
let deserialized: CallRequest = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized.from, None);
assert_eq!(deserialized.to, Address::from_low_u64_be(5));
assert_eq!(deserialized.gas, Some(21_000.into()));
assert_eq!(deserialized.gas_price, None);
assert_eq!(deserialized.value, Some(5_000_000.into()));
assert_eq!(deserialized.data, Some(vec![1, 2, 3].into()));
}
#[test]
fn should_serialize_transaction_request() {
let tx_request = TransactionRequest {
from: Address::from_low_u64_be(5),
to: None,
gas: Some(21_000.into()),
gas_price: None,
value: Some(5_000_000.into()),
data: Some(vec![1, 2, 3].into()),
nonce: None,
condition: Some(TransactionCondition::Block(5)),
};
let serialized = serde_json::to_string_pretty(&tx_request).unwrap();
assert_eq!(
serialized,
r#"{
"from": "0x0000000000000000000000000000000000000005",
"gas": "0x5208",
"value": "0x4c4b40",
"data": "0x010203",
"condition": {
"block": 5
}
}"#
);
}
#[test]
fn should_deserialize_transaction_request() {
let serialized = r#"{
"from": "0x0000000000000000000000000000000000000005",
"gas": "0x5208",
"value": "0x4c4b40",
"data": "0x010203",
"condition": {
"block": 5
}
}"#;
let deserialized: TransactionRequest = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized.from, Address::from_low_u64_be(5));
assert_eq!(deserialized.to, None);
assert_eq!(deserialized.gas, Some(21_000.into()));
assert_eq!(deserialized.gas_price, None);
assert_eq!(deserialized.value, Some(5_000_000.into()));
assert_eq!(deserialized.data, Some(vec![1, 2, 3].into()));
assert_eq!(deserialized.nonce, None);
assert_eq!(deserialized.condition, Some(TransactionCondition::Block(5)));
}
}