stratus/eth/primitives/
wei.rs1use std::str::FromStr;
2
3use alloy_primitives::U256;
4use anyhow::Context;
5use display_json::DebugAsJson;
6#[cfg(test)]
7use fake::Dummy;
8#[cfg(test)]
9use fake::Faker;
10use sqlx::types::BigDecimal;
11
12#[derive(DebugAsJson, derive_more::Display, Clone, Copy, Default, PartialOrd, Ord, PartialEq, Eq, derive_more::Sub, serde::Serialize, serde::Deserialize)]
14pub struct Wei(pub U256);
15
16impl Wei {
17 pub const ZERO: Wei = Wei(U256::ZERO);
18 pub const ONE: Wei = Wei(U256::ONE);
19 pub const TEST_BALANCE: Wei = Wei(U256::from_limbs([u64::MAX, 0, 0, 0]));
20
21 pub fn from_hex_str(hex: &str) -> Result<Self, anyhow::Error> {
43 let hex = hex.trim_start_matches("0x");
44 let u256 = U256::from_str_radix(hex, 16)?;
45 Ok(Self(u256))
46 }
47
48 #[deprecated(since = "0.20.1", note = "Use from_hex_str instead")]
50 pub fn from_str_hex(hex: &str) -> Result<Self, anyhow::Error> {
51 Self::from_hex_str(hex)
52 }
53}
54
55#[cfg(test)]
56impl Dummy<Faker> for Wei {
57 fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &Faker, rng: &mut R) -> Self {
58 rng.next_u64().into()
59 }
60}
61
62impl From<u8> for Wei {
67 fn from(value: u8) -> Self {
68 Self(U256::from(value))
69 }
70}
71
72impl From<u16> for Wei {
73 fn from(value: u16) -> Self {
74 Self(U256::from(value))
75 }
76}
77
78impl From<u32> for Wei {
79 fn from(value: u32) -> Self {
80 Self(U256::from(value))
81 }
82}
83
84impl From<u64> for Wei {
85 fn from(value: u64) -> Self {
86 Self(U256::from(value))
87 }
88}
89
90impl From<u128> for Wei {
91 fn from(value: u128) -> Self {
92 Self(U256::from(value))
93 }
94}
95
96impl From<U256> for Wei {
97 fn from(value: U256) -> Self {
98 Self(value)
99 }
100}
101
102impl From<usize> for Wei {
103 fn from(value: usize) -> Self {
104 Self(U256::from(value))
105 }
106}
107
108impl From<i32> for Wei {
109 fn from(value: i32) -> Self {
110 Self(U256::from(value as u32))
111 }
112}
113
114impl From<[u64; 4]> for Wei {
115 fn from(value: [u64; 4]) -> Self {
116 Self(U256::from_limbs(value))
117 }
118}
119
120impl TryFrom<BigDecimal> for Wei {
121 type Error = anyhow::Error;
122
123 fn try_from(value: BigDecimal) -> Result<Self, Self::Error> {
124 let value_str = value.to_string();
125 Ok(Wei(U256::from_str_radix(&value_str, 10)?))
126 }
127}
128
129impl TryFrom<Wei> for u128 {
134 type Error = anyhow::Error;
135
136 fn try_from(value: Wei) -> Result<Self, Self::Error> {
137 u128::try_from(value.0).context("wei conversion failed")
138 }
139}
140
141impl From<Wei> for U256 {
142 fn from(value: Wei) -> Self {
143 value.0
144 }
145}
146
147impl TryFrom<Wei> for BigDecimal {
148 type Error = anyhow::Error;
149 fn try_from(value: Wei) -> Result<Self, Self::Error> {
150 Ok(BigDecimal::from_str(&value.0.to_string())?)
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
169 fn test_from_hex_str() {
170 let wei = Wei::from_hex_str("1a").unwrap();
172 assert_eq!(wei, Wei::from(26u64));
173
174 let wei = Wei::from_hex_str("0x1a").unwrap();
176 assert_eq!(wei, Wei::from(26u64));
177
178 let wei = Wei::from_hex_str("0xffff").unwrap();
180 assert_eq!(wei, Wei::from(65535u64));
181 }
182}