1use serde::{Deserialize, Serialize};
22use sp_core::U256;
23use std::fmt::Debug;
24
25#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)]
34#[serde(untagged)]
35pub enum NumberOrHex {
36 Number(u64),
38 Hex(U256),
40}
41
42impl Default for NumberOrHex {
43 fn default() -> Self {
44 Self::Number(Default::default())
45 }
46}
47
48impl NumberOrHex {
49 pub fn into_u256(self) -> U256 {
51 match self {
52 NumberOrHex::Number(n) => n.into(),
53 NumberOrHex::Hex(h) => h,
54 }
55 }
56}
57
58impl From<u32> for NumberOrHex {
59 fn from(n: u32) -> Self {
60 NumberOrHex::Number(n.into())
61 }
62}
63
64impl From<u64> for NumberOrHex {
65 fn from(n: u64) -> Self {
66 NumberOrHex::Number(n)
67 }
68}
69
70impl From<u128> for NumberOrHex {
71 fn from(n: u128) -> Self {
72 NumberOrHex::Hex(n.into())
73 }
74}
75
76impl From<U256> for NumberOrHex {
77 fn from(n: U256) -> Self {
78 NumberOrHex::Hex(n)
79 }
80}
81
82pub struct TryFromIntError(pub(crate) ());
84
85impl TryFrom<NumberOrHex> for u32 {
86 type Error = TryFromIntError;
87 fn try_from(num_or_hex: NumberOrHex) -> Result<u32, Self::Error> {
88 num_or_hex.into_u256().try_into().map_err(|_| TryFromIntError(()))
89 }
90}
91
92impl TryFrom<NumberOrHex> for u64 {
93 type Error = TryFromIntError;
94 fn try_from(num_or_hex: NumberOrHex) -> Result<u64, Self::Error> {
95 num_or_hex.into_u256().try_into().map_err(|_| TryFromIntError(()))
96 }
97}
98
99impl TryFrom<NumberOrHex> for u128 {
100 type Error = TryFromIntError;
101 fn try_from(num_or_hex: NumberOrHex) -> Result<u128, Self::Error> {
102 num_or_hex.into_u256().try_into().map_err(|_| TryFromIntError(()))
103 }
104}
105
106impl From<NumberOrHex> for U256 {
107 fn from(num_or_hex: NumberOrHex) -> U256 {
108 num_or_hex.into_u256()
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use crate::assert_deser;
116
117 #[test]
118 fn should_serialize_and_deserialize() {
119 assert_deser(r#""0x1234""#, NumberOrHex::Hex(0x1234.into()));
120 assert_deser(r#""0x0""#, NumberOrHex::Hex(0.into()));
121 assert_deser(r#"5"#, NumberOrHex::Number(5));
122 assert_deser(r#"10000"#, NumberOrHex::Number(10000));
123 assert_deser(r#"0"#, NumberOrHex::Number(0));
124 assert_deser(r#"1000000000000"#, NumberOrHex::Number(1000000000000));
125 }
126}