1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use serde::{
de::{Deserializer, SeqAccess, Visitor},
ser::{SerializeSeq, Serializer},
Deserialize, Serialize,
};
use strum_macros::{Display, EnumString};
#[derive(Copy, Clone, Debug, Display, EnumString)]
#[strum(serialize_all = "snake_case")]
pub enum QuantityChoice {
Base,
Quote,
Contract,
}
#[cfg(feature = "f32")]
pub type Float = f32;
#[cfg(not(feature = "f32"))]
pub type Float = f64;
#[derive(Copy, Clone, Debug)]
pub struct Order {
pub price: Float,
pub quantity: Float,
}
impl PartialEq for Order {
fn eq(&self, other: &Self) -> bool {
self.price == other.price && self.quantity == other.quantity
}
}
impl Eq for Order {}
impl Serialize for Order {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let len: usize = 2;
let mut seq = serializer.serialize_seq(Some(len))?;
seq.serialize_element(&self.price)?;
let quantity = format!("{:.9}", self.quantity)
.as_str()
.parse::<f64>()
.unwrap();
seq.serialize_element(&quantity)?;
seq.end()
}
}
struct OrderVisitor;
impl<'de> Visitor<'de> for OrderVisitor {
type Value = Order;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a nonempty sequence of numbers")
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Order, V::Error>
where
V: SeqAccess<'de>,
{
let mut vec = Vec::<f64>::new();
while let Some(elem) = visitor.next_element()? {
vec.push(elem);
}
let order = Order {
price: vec[0] as Float,
quantity: vec[1] as Float,
};
Ok(order)
}
}
impl<'de> Deserialize<'de> for Order {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(OrderVisitor)
}
}
#[cfg(test)]
mod tests {
use crate::compact::Order;
#[test]
fn order_serialize() {
let order = Order {
price: 59999.8,
quantity: 1.7000000001,
};
let text = serde_json::to_string(&order).unwrap();
assert_eq!(text.as_str(), "[59999.8,1.7]");
let order = Order {
price: 59999.8,
quantity: 1.7000000006,
};
let text = serde_json::to_string(&order).unwrap();
assert_eq!(text.as_str(), "[59999.8,1.700000001]");
}
#[test]
fn order_deserialize() {
let expected = Order {
price: 59999.8,
quantity: 1.7,
};
let actual = serde_json::from_str::<Order>("[59999.8,1.7,101999.66,1.7]").unwrap();
assert_eq!(expected.price, actual.price);
assert_eq!(expected.quantity, actual.quantity);
}
}