cfx_rpc_eth_types/
call.rs1use crate::{BlockId, BlockOverrides, TransactionRequest};
2use cfx_bytes::Bytes;
3
4#[derive(Clone, Debug, Default, PartialEq, Eq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
8pub struct Bundle {
9 pub transactions: Vec<TransactionRequest>,
11 #[cfg_attr(
13 feature = "serde",
14 serde(default, skip_serializing_if = "Option::is_none")
15 )]
16 pub block_override: Option<BlockOverrides>,
17}
18
19impl From<Vec<TransactionRequest>> for Bundle {
20 fn from(tx_request: Vec<TransactionRequest>) -> Self {
22 Self {
23 transactions: tx_request,
24 block_override: None,
25 }
26 }
27}
28
29#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
33pub struct StateContext {
34 #[cfg_attr(
36 feature = "serde",
37 serde(skip_serializing_if = "Option::is_none")
38 )]
39 pub block_number: Option<BlockId>,
40 #[cfg_attr(
42 feature = "serde",
43 serde(skip_serializing_if = "Option::is_none")
44 )]
45 #[doc(alias = "tx_index")]
46 pub transaction_index: Option<TransactionIndex>,
47}
48
49#[derive(Clone, Debug, Default, PartialEq, Eq)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
53pub struct EthCallResponse {
54 #[cfg_attr(
56 feature = "serde",
57 serde(skip_serializing_if = "Option::is_none")
58 )]
59 pub value: Option<Bytes>,
60 #[cfg_attr(
62 feature = "serde",
63 serde(skip_serializing_if = "Option::is_none")
64 )]
65 pub error: Option<String>,
66}
67
68impl EthCallResponse {
69 pub fn ensure_ok(self) -> Result<Bytes, String> {
71 match self.value {
72 Some(output) => Ok(output),
73 None => {
74 Err(self.error.unwrap_or_else(|| "Unknown error".to_string()))
75 }
76 }
77 }
78}
79
80#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
82pub enum TransactionIndex {
83 #[default]
85 All,
86 Index(usize),
88}
89
90impl TransactionIndex {
91 pub const fn is_all(&self) -> bool { matches!(self, Self::All) }
93
94 pub const fn is_index(&self) -> bool { matches!(self, Self::Index(_)) }
96
97 pub const fn index(&self) -> Option<usize> {
99 match self {
100 Self::All => None,
101 Self::Index(idx) => Some(*idx),
102 }
103 }
104}
105
106impl From<usize> for TransactionIndex {
107 fn from(index: usize) -> Self { Self::Index(index) }
108}
109
110#[cfg(feature = "serde")]
111impl serde::Serialize for TransactionIndex {
112 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113 where S: serde::Serializer {
114 match self {
115 Self::All => serializer.serialize_i8(-1),
116 Self::Index(idx) => idx.serialize(serializer),
117 }
118 }
119}
120
121#[cfg(feature = "serde")]
122impl<'de> serde::Deserialize<'de> for TransactionIndex {
123 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
124 where D: serde::Deserializer<'de> {
125 match isize::deserialize(deserializer)? {
126 -1 => Ok(Self::All),
127 idx if idx < -1 => Err(serde::de::Error::custom(format!(
128 "Invalid transaction index, expected -1 or positive integer, got {}",
129 idx
130 ))),
131 idx => Ok(Self::Index(idx as usize)),
132 }
133 }
134}