Skip to main content

bulk_client/common/
side.rs

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