Skip to main content

superposition_assets/
lib.rs

1#![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 FromStr for Asset {
67    type Err = InvalidAsset;
68
69    fn from_str(x: &str) -> Result<Self, Self::Err> {
70        match x {
71            "usdc" | "USDC" => Ok(Asset::USDC),
72            "arb" | "ARB" => Ok(Asset::ARB),
73            "weth" | "WETH" => Ok(Asset::WETH),
74            _ => Err(InvalidAsset),
75        }
76    }
77}
78
79impl Asset {
80    pub fn from_str(x: &str) -> Self {
81        x.into()
82    }
83
84    pub fn try_from_str(x: &str) -> Result<Self, InvalidAsset> {
85        x.try_into().map_err(|_| InvalidAsset)
86    }
87
88    #[cfg(feature = "alloc")]
89    pub fn from_string(x: String) -> Self {
90        x.into()
91    }
92
93    #[cfg(feature = "alloc")]
94    pub fn try_from_string(x: String) -> Result<Self, InvalidAsset> {
95        x.try_into().map_err(|_| InvalidAsset)
96    }
97}
98
99impl From<&str> for Asset {
100    fn from(x: &str) -> Self {
101        x.parse()
102            .unwrap_or_else(|_| panic!("bad asset: {x}"))
103    }
104}
105
106impl TryFrom<u8> for Asset {
107    type Error = InvalidAsset;
108
109    fn try_from(x: u8) -> Result<Self, Self::Error> {
110        match x {
111            0 => Ok(Asset::USDC),
112            1 => Ok(Asset::ARB),
113            2 => Ok(Asset::WETH),
114            _ => Err(InvalidAsset),
115        }
116    }
117}
118
119macro_rules! impl_asset_int {
120    ($($ty:ty),* $(,)?) => {
121        $(
122            impl TryFrom<$ty> for Asset {
123                type Error = InvalidAsset;
124
125                fn try_from(x: $ty) -> Result<Self, Self::Error> {
126                    let x = u8::try_from(x).map_err(|_| InvalidAsset)?;
127                    Asset::try_from(x)
128                }
129            }
130
131            impl From<Asset> for $ty {
132                fn from(x: Asset) -> Self {
133                    x as u8 as $ty
134                }
135            }
136        )*
137    };
138}
139
140impl_asset_int!(u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);