Skip to main content

df_hyperliquid_core/markets/
dex.rs

1//! Which perp dex a read or a coin is about: a request without `dex` is the main dex's, one with
2//! `"dex":"xyz"` that HIP-3 dex's. A HIP-3 coin is `dex:SYMBOL`; its asset id is
3//! [`Asset::hip3`](crate::utils::asset::Asset::hip3).
4
5#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
6pub enum Dex<'a> {
7    /// The main dex, the first in `perpDexs`.
8    #[default]
9    Main,
10    /// A HIP-3 dex by its name: `xyz`, the `xyz:` of its coins.
11    Hip3(&'a str),
12}
13
14impl<'a> Dex<'a> {
15    /// The dex a coin trades on: `xyz:TSLA` on `xyz`, `BTC` on the main dex.
16    #[must_use]
17    pub fn of_coin(coin: &'a str) -> Dex<'a> {
18        match coin.split_once(':') {
19            Some((dex, _)) => Dex::Hip3(dex),
20            None => Dex::Main,
21        }
22    }
23
24    /// The `dex` a request names; `None` for the main dex.
25    #[must_use]
26    pub const fn name(self) -> Option<&'a str> {
27        match self {
28            Dex::Main => None,
29            Dex::Hip3(name) => Some(name),
30        }
31    }
32}
33
34/// `xyz:TSLA` as `("xyz", "TSLA")`. `None` for a main-dex coin or an empty part.
35#[must_use]
36pub fn split_coin(coin: &str) -> Option<(&str, &str)> {
37    let (dex, symbol) = coin.split_once(':')?;
38    (!dex.is_empty() && !symbol.is_empty()).then_some((dex, symbol))
39}
40
41/// `xyz` and `TSLA` as `xyz:TSLA`.
42#[must_use]
43pub fn coin(dex: &str, symbol: &str) -> String {
44    format!("{dex}:{symbol}")
45}
46
47#[cfg(test)]
48#[path = "tests/dex.rs"]
49mod tests;