superposition_assets/
lib.rs1#![cfg_attr(not(any(feature = "proptest", feature = "arbitrary")), no_std)]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6#[cfg(feature = "alloc")]
7use alloc::string::String;
8
9use core::str::FromStr;
10
11#[repr(u8)]
12#[derive(Clone, PartialEq, Eq, Debug)]
13#[cfg_attr(
14 feature = "borsh",
15 derive(borsh::BorshDeserialize, borsh::BorshSerialize),
16 borsh(use_discriminant = true)
17)]
18#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
19#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
20#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
21pub enum Asset {
22 USDC = 0,
23 ARB = 1,
24 WETH = 2,
25}
26
27const fn decode(x: &[u8]) -> [u8; 20] {
28 match const_hex::const_decode_to_array::<20>(x) {
29 Ok(r) => r,
30 Err(_) => panic!(),
31 }
32}
33
34impl Asset {
35 fn addr(&self) -> [u8; 20] {
36 match self {
37 Asset::USDC => decode(b"af88d065e77c8cC2239327C5EDb3A432268e5831"),
38 Asset::ARB => decode(b"912ce59144191c1204e64559fe8253a0e49e6548"),
39 Asset::WETH => decode(b"82af49447d8a07e3bd95bd0d56f35241523fbab1"),
40 }
41 }
42}
43
44impl From<Asset> for [u8; 20] {
45 fn from(x: Asset) -> Self {
46 x.addr()
47 }
48}
49
50impl From<&Asset> for [u8; 20] {
51 fn from(x: &Asset) -> Self {
52 x.addr()
53 }
54}
55
56#[cfg(feature = "alloc")]
57impl From<String> for Asset {
58 fn from(x: String) -> Self {
59 x.as_str().into()
60 }
61}
62
63#[derive(Clone, Copy, Debug, PartialEq, Eq)]
64pub struct InvalidAsset;
65
66impl core::fmt::Display for InvalidAsset {
67 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
68 write!(f, "{self:?}")
69 }
70}
71
72impl core::error::Error for InvalidAsset {}
73
74impl FromStr for Asset {
75 type Err = InvalidAsset;
76
77 fn from_str(x: &str) -> Result<Self, Self::Err> {
78 match x {
79 "usdc" | "USDC" => Ok(Asset::USDC),
80 "arb" | "ARB" => Ok(Asset::ARB),
81 "weth" | "WETH" => Ok(Asset::WETH),
82 _ => Err(InvalidAsset),
83 }
84 }
85}
86
87impl Asset {
88 pub fn from_str(x: &str) -> Self {
89 x.into()
90 }
91
92 pub fn try_from_str(x: &str) -> Result<Self, InvalidAsset> {
93 x.try_into().map_err(|_| InvalidAsset)
94 }
95
96 #[cfg(feature = "alloc")]
97 pub fn from_string(x: String) -> Self {
98 x.into()
99 }
100
101 #[cfg(feature = "alloc")]
102 pub fn try_from_string(x: String) -> Result<Self, InvalidAsset> {
103 x.try_into().map_err(|_| InvalidAsset)
104 }
105}
106
107impl From<&str> for Asset {
108 fn from(x: &str) -> Self {
109 x.parse()
110 .unwrap_or_else(|_| panic!("bad asset: {x}"))
111 }
112}
113
114impl TryFrom<u8> for Asset {
115 type Error = InvalidAsset;
116
117 fn try_from(x: u8) -> Result<Self, Self::Error> {
118 match x {
119 0 => Ok(Asset::USDC),
120 1 => Ok(Asset::ARB),
121 2 => Ok(Asset::WETH),
122 _ => Err(InvalidAsset),
123 }
124 }
125}
126
127macro_rules! impl_asset_int {
128 ($($ty:ty),* $(,)?) => {
129 $(
130 impl TryFrom<$ty> for Asset {
131 type Error = InvalidAsset;
132
133 fn try_from(x: $ty) -> Result<Self, Self::Error> {
134 let x = u8::try_from(x).map_err(|_| InvalidAsset)?;
135 Asset::try_from(x)
136 }
137 }
138
139 impl From<Asset> for $ty {
140 fn from(x: Asset) -> Self {
141 x as u8 as $ty
142 }
143 }
144 )*
145 };
146}
147
148impl_asset_int!(u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);