use num_enum::{FromPrimitive, IntoPrimitive};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use eyre::bail;
#[derive(
Clone, Copy, Debug, Eq, PartialEq, Default, IntoPrimitive, FromPrimitive, Hash, Ord, PartialOrd,
)]
#[repr(u8)]
pub enum Side {
#[default]
Buy = 0,
Sell = 1,
}
impl Side {
pub fn dir(&self) -> f64 {
match self {
Side::Buy => 1.0,
Side::Sell => -1.0,
}
}
}
impl Display for Side {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Side::Buy => write!(f, "Buy"),
Side::Sell => write!(f, "Sell"),
}
}
}
impl Into<f64> for Side {
fn into(self) -> f64 {
match self {
Side::Buy => 1.0,
Side::Sell => -1.0,
}
}
}
impl From<bool> for Side {
fn from(v: bool) -> Self {
if v {
Side::Buy
} else {
Side::Sell
}
}
}
impl FromStr for Side {
type Err = eyre::Error;
fn from_str(s: &str) -> eyre::Result<Self> {
match s {
"Buy" | "buy" | "BUY" | "b" | "B" => Ok(Side::Buy),
"Sell" | "sell" | "SELL" | "s" | "S" => Ok(Side::Sell),
_ => bail!(
"unknown side '{s}'\n → expected Buy or Sell"
),
}
}
}
impl Serialize for Side {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bool(*self == Side::Buy)
}
}
impl<'de> Deserialize<'de> for Side {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = bool::deserialize(deserializer)?;
Ok(if value { Side::Buy } else { Side::Sell })
}
}