alloy_primitives/
common.rs1use crate::Address;
2
3#[cfg(feature = "rlp")]
4use alloy_rlp::{Buf, BufMut, Decodable, EMPTY_STRING_CODE, Encodable};
5
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary, proptest_derive::Arbitrary))]
10#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
11#[doc(alias = "TransactionKind")]
12pub enum TxKind {
13 #[default]
15 Create,
16 Call(Address),
18}
19
20impl From<Option<Address>> for TxKind {
21 #[inline]
23 fn from(value: Option<Address>) -> Self {
24 match value {
25 None => Self::Create,
26 Some(addr) => Self::Call(addr),
27 }
28 }
29}
30
31impl From<Address> for TxKind {
32 #[inline]
34 fn from(value: Address) -> Self {
35 Self::Call(value)
36 }
37}
38
39impl From<TxKind> for Option<Address> {
40 #[inline]
42 fn from(value: TxKind) -> Self {
43 value.to().copied()
44 }
45}
46
47impl TxKind {
48 pub const fn to(&self) -> Option<&Address> {
50 match self {
51 Self::Create => None,
52 Self::Call(to) => Some(to),
53 }
54 }
55
56 pub const fn into_to(self) -> Option<Address> {
59 match self {
60 Self::Create => None,
61 Self::Call(to) => Some(to),
62 }
63 }
64
65 #[inline]
67 pub const fn is_create(&self) -> bool {
68 matches!(self, Self::Create)
69 }
70
71 #[inline]
73 pub const fn is_call(&self) -> bool {
74 matches!(self, Self::Call(_))
75 }
76
77 #[inline]
79 pub const fn size(&self) -> usize {
80 core::mem::size_of::<Self>()
81 }
82}
83
84#[cfg(feature = "rlp")]
85impl Encodable for TxKind {
86 fn encode(&self, out: &mut dyn BufMut) {
87 match self {
88 Self::Call(to) => to.encode(out),
89 Self::Create => out.put_u8(EMPTY_STRING_CODE),
90 }
91 }
92
93 fn length(&self) -> usize {
94 match self {
95 Self::Call(to) => to.length(),
96 Self::Create => 1, }
98 }
99}
100
101#[cfg(feature = "rlp")]
102impl Decodable for TxKind {
103 fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
104 if let Some(&first) = buf.first() {
105 if first == EMPTY_STRING_CODE {
106 buf.advance(1);
107 Ok(Self::Create)
108 } else {
109 let addr = <Address as Decodable>::decode(buf)?;
110 Ok(Self::Call(addr))
111 }
112 } else {
113 Err(alloy_rlp::Error::InputTooShort)
114 }
115 }
116}
117
118#[cfg(feature = "serde")]
119impl serde::Serialize for TxKind {
120 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
121 self.to().serialize(serializer)
122 }
123}
124
125#[cfg(feature = "serde")]
126impl<'de> serde::Deserialize<'de> for TxKind {
127 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
128 Ok(Option::<Address>::deserialize(deserializer)?.into())
129 }
130}