anvil_zksync_types/
numbers.rs1use zksync_types::U256;
2
3#[derive(Clone, Debug, Eq, PartialEq)]
4pub enum Sign {
5 NonNegative,
6 Negative,
7}
8impl std::fmt::Display for Sign {
9 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10 f.write_str(match self {
11 Sign::NonNegative => "+",
12 Sign::Negative => "-",
13 })
14 }
15}
16
17#[derive(Clone, Debug, Eq, PartialEq)]
18pub struct SignedU256 {
19 pub sign: Sign,
20 pub inner: U256,
21}
22impl std::fmt::Display for SignedU256 {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 let Self { sign, inner } = self;
25 if *sign == Sign::Negative {
26 write!(f, "-")?;
27 }
28 write!(f, "{inner}")
29 }
30}
31
32impl<T> From<T> for SignedU256
33where
34 T: Into<U256>,
35{
36 fn from(val: T) -> Self {
37 SignedU256 {
38 sign: Sign::NonNegative,
39 inner: val.into(),
40 }
41 }
42}
43
44impl From<SignedU256> for NumberExponentialRepr {
45 fn from(val: SignedU256) -> Self {
49 to_exp_notation(val, 4, true)
50 }
51}
52
53pub struct NumberExponentialRepr {
54 pub value: SignedU256,
55 pub mantissa: String,
56 pub exponent: usize,
57}
58
59fn to_exp_notation(
73 value: SignedU256,
74 precision: usize,
75 trim_end_zeros: bool,
76) -> NumberExponentialRepr {
77 let stringified = value.inner.to_string();
78 let exponent = stringified.len() - 1;
79 let mut mantissa = stringified.chars().take(precision).collect::<String>();
80
81 if trim_end_zeros {
83 mantissa = mantissa.trim_end_matches('0').to_string();
84 }
85
86 if mantissa.len() > 1 {
90 mantissa.insert(1, '.');
91 }
92 NumberExponentialRepr {
93 value,
94 mantissa,
95 exponent,
96 }
97}
98
99impl std::fmt::Display for NumberExponentialRepr {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 let NumberExponentialRepr {
102 value: SignedU256 { sign, .. },
103 mantissa,
104 exponent,
105 } = self;
106 let sign = if sign == &Sign::Negative { "-" } else { "" };
107 f.write_fmt(format_args!("{sign}{mantissa}e{exponent}"))?;
108 Ok(())
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use crate::numbers::{to_exp_notation, SignedU256};
115
116 #[test]
117 fn test_format_to_exponential_notation() {
118 let value = 1234124124u64;
119
120 let formatted = to_exp_notation(SignedU256::from(value), 4, false);
121 assert_eq!(formatted.to_string(), "1.234e9");
122
123 let formatted = to_exp_notation(SignedU256::from(value), 3, false);
124 assert_eq!(formatted.to_string(), "1.23e9");
125
126 let value = 10000000u64;
127
128 let formatted = to_exp_notation(SignedU256::from(value), 4, false);
129 assert_eq!(formatted.to_string(), "1.000e7");
130
131 let formatted = to_exp_notation(SignedU256::from(value), 3, true);
132 assert_eq!(formatted.to_string(), "1e7");
133 }
134}