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