df_hyperliquid_core/client/evm/abi/
token.rs1use crate::client::evm::u256::U256;
5use crate::utils::Address;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum Token {
10 Uint(U256),
11 Int(U256),
13 Address(Address),
14 Bool(bool),
15 String(String),
16 Bytes(Vec<u8>),
17 Fixed(Vec<u8>),
19 Array(Vec<Token>),
21 Tuple(Vec<Token>),
22}
23
24impl Token {
25 #[must_use]
26 pub fn uint(value: impl Into<U256>) -> Token {
27 Token::Uint(value.into())
28 }
29
30 #[must_use]
31 pub fn int(value: i128) -> Token {
32 let magnitude = U256::from_u128(value.unsigned_abs());
33 Token::Int(match value < 0 {
34 true => negated(magnitude),
35 false => magnitude,
36 })
37 }
38
39 #[must_use]
40 pub fn address(address: Address) -> Token {
41 Token::Address(address)
42 }
43
44 #[must_use]
45 pub fn as_u256(&self) -> Option<U256> {
46 match self {
47 Token::Uint(value) => Some(*value),
48 _ => None,
49 }
50 }
51
52 #[must_use]
53 pub fn as_u128(&self) -> Option<u128> {
54 self.as_u256().and_then(U256::to_u128)
55 }
56
57 #[must_use]
58 pub fn as_u64(&self) -> Option<u64> {
59 self.as_u256().and_then(U256::to_u64)
60 }
61
62 #[must_use]
63 pub fn as_u32(&self) -> Option<u32> {
64 self.as_u64().and_then(|value| u32::try_from(value).ok())
65 }
66
67 #[must_use]
68 pub fn as_u16(&self) -> Option<u16> {
69 self.as_u64().and_then(|value| u16::try_from(value).ok())
70 }
71
72 #[must_use]
73 pub fn as_u8(&self) -> Option<u8> {
74 self.as_u64().and_then(|value| u8::try_from(value).ok())
75 }
76
77 #[must_use]
79 pub fn as_i128(&self) -> Option<i128> {
80 let Token::Int(value) = self else { return None };
81 match value.bits() == 256 {
82 false => value.to_u128().and_then(|value| i128::try_from(value).ok()),
83 true => {
84 let magnitude = negated(*value).to_u128()?;
85 match magnitude == i128::MIN.unsigned_abs() {
86 true => Some(i128::MIN),
87 false => i128::try_from(magnitude).ok().map(|magnitude| -magnitude),
88 }
89 }
90 }
91 }
92
93 #[must_use]
94 pub fn as_i64(&self) -> Option<i64> {
95 self.as_i128().and_then(|value| i64::try_from(value).ok())
96 }
97
98 #[must_use]
99 pub fn as_i8(&self) -> Option<i8> {
100 self.as_i128().and_then(|value| i8::try_from(value).ok())
101 }
102
103 #[must_use]
104 pub fn as_address(&self) -> Option<Address> {
105 match self {
106 Token::Address(address) => Some(*address),
107 _ => None,
108 }
109 }
110
111 #[must_use]
112 pub fn as_bool(&self) -> Option<bool> {
113 match self {
114 Token::Bool(value) => Some(*value),
115 _ => None,
116 }
117 }
118
119 #[must_use]
120 pub fn as_str(&self) -> Option<&str> {
121 match self {
122 Token::String(text) => Some(text),
123 _ => None,
124 }
125 }
126
127 #[must_use]
129 pub fn as_bytes(&self) -> Option<&[u8]> {
130 match self {
131 Token::Bytes(bytes) | Token::Fixed(bytes) => Some(bytes),
132 _ => None,
133 }
134 }
135
136 #[must_use]
138 pub fn as_items(&self) -> Option<&[Token]> {
139 match self {
140 Token::Array(items) | Token::Tuple(items) => Some(items),
141 _ => None,
142 }
143 }
144}
145
146pub(super) fn negated(value: U256) -> U256 {
148 match value.checked_sub(U256::ONE) {
149 Some(less) => U256::MAX.checked_sub(less).unwrap_or(U256::ZERO),
150 None => U256::ZERO,
151 }
152}