Skip to main content

bulk_client/common/
side.rs

1use eyre::bail;
2use num_enum::{FromPrimitive, IntoPrimitive};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::fmt::{Display, Formatter};
5use std::str::FromStr;
6
7/// Buy / Sell
8#[derive(
9    Clone, Copy, Debug, Eq, PartialEq, Default, IntoPrimitive, FromPrimitive, Hash, Ord, PartialOrd,
10)]
11#[repr(u8)]
12pub enum Side {
13    #[default]
14    Buy = 0,
15    Sell = 1,
16}
17
18impl Side {
19    pub fn dir(&self) -> f64 {
20        match self {
21            Side::Buy => 1.0,
22            Side::Sell => -1.0,
23        }
24    }
25}
26
27/// Formatting
28impl Display for Side {
29    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
30        match self {
31            Side::Buy => write!(f, "Buy"),
32            Side::Sell => write!(f, "Sell"),
33        }
34    }
35}
36
37impl Into<f64> for Side {
38    fn into(self) -> f64 {
39        match self {
40            Side::Buy => 1.0,
41            Side::Sell => -1.0,
42        }
43    }
44}
45
46impl From<bool> for Side {
47    fn from(v: bool) -> Self {
48        if v {
49            Side::Buy
50        } else {
51            Side::Sell
52        }
53    }
54}
55
56impl FromStr for Side {
57    type Err = eyre::Error;
58
59    fn from_str(s: &str) -> eyre::Result<Self> {
60        match s {
61            "Buy" | "buy" | "BUY" | "b" | "B" => Ok(Side::Buy),
62            "Sell" | "sell" | "SELL" | "s" | "S" => Ok(Side::Sell),
63            _ => bail!("unknown side '{s}'\n  → expected Buy or Sell"),
64        }
65    }
66}
67
68// Custom serialization to store as u8 (binary) or String (human-readable)
69impl Serialize for Side {
70    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71    where
72        S: Serializer,
73    {
74        serializer.serialize_bool(*self == Side::Buy)
75    }
76}
77
78// Custom deserialization from u8 (binary) or String (human-readable)
79impl<'de> Deserialize<'de> for Side {
80    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
81    where
82        D: Deserializer<'de>,
83    {
84        let value = bool::deserialize(deserializer)?;
85        Ok(if value { Side::Buy } else { Side::Sell })
86    }
87}