df_hyperliquid_core/markets/
side.rs1use std::fmt;
5
6use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
7
8use crate::utils::dec::Round;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
14pub enum Side {
15 Buy,
16 Sell,
17}
18
19impl Side {
20 pub const ALL: [Side; 2] = [Side::Buy, Side::Sell];
21
22 #[must_use]
24 pub fn parse(said: &str) -> Option<Side> {
25 match said {
26 "B" => Some(Side::Buy),
27 "A" => Some(Side::Sell),
28 _ => None,
29 }
30 }
31
32 #[must_use]
34 pub const fn wire(self) -> &'static str {
35 match self {
36 Side::Buy => "B",
37 Side::Sell => "A",
38 }
39 }
40
41 #[must_use]
42 pub const fn is_buy(self) -> bool {
43 matches!(self, Side::Buy)
44 }
45
46 #[must_use]
47 pub const fn other(self) -> Side {
48 match self {
49 Side::Buy => Side::Sell,
50 Side::Sell => Side::Buy,
51 }
52 }
53
54 #[must_use]
57 pub const fn price_rounding(self) -> Round {
58 match self {
59 Side::Buy => Round::Down,
60 Side::Sell => Round::Up,
61 }
62 }
63}
64
65impl fmt::Display for Side {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.write_str(self.wire())
68 }
69}
70
71impl Serialize for Side {
72 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
73 serializer.serialize_str(self.wire())
74 }
75}
76
77impl<'de> Deserialize<'de> for Side {
78 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
79 let said = <std::borrow::Cow<'de, str>>::deserialize(deserializer)?;
80 Side::parse(&said).ok_or_else(|| de::Error::custom(format!("`{said}` is not a side; expected B or A")))
81 }
82}
83
84#[cfg(test)]
85#[path = "tests/side.rs"]
86mod tests;