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