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
use serde::{
de::{Deserializer, SeqAccess, Visitor},
ser::{SerializeSeq, Serializer},
Deserialize, Serialize,
};
pub struct Order {
pub price: f64,
pub quantity_base: f64,
pub quantity_quote: f64,
pub quantity_contract: Option<f64>,
}
impl Serialize for Order {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let len: usize = if self.quantity_contract.is_some() {
4
} else {
3
};
let mut seq = serializer.serialize_seq(Some(len))?;
seq.serialize_element(&self.price)?;
let quantity_base = format!("{:.9}", self.quantity_base)
.as_str()
.parse::<f64>()
.unwrap();
let quantity_quote = format!("{:.9}", self.quantity_quote)
.as_str()
.parse::<f64>()
.unwrap();
seq.serialize_element(&quantity_base)?;
seq.serialize_element(&quantity_quote)?;
if let Some(qc) = self.quantity_contract {
seq.serialize_element(&qc)?;
}
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],
quantity_base: vec[1],
quantity_quote: vec[2],
quantity_contract: if vec.len() == 4 { Some(vec[3]) } else { None },
};
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::order::Order;
#[test]
fn order_serialize() {
let order = Order {
price: 59999.8,
quantity_base: 1.7000000001,
quantity_quote: 59999.8 * 1.7,
quantity_contract: Some(1.7),
};
let text = serde_json::to_string(&order).unwrap();
assert_eq!(text.as_str(), "[59999.8,1.7,101999.66,1.7]");
let order = Order {
price: 59999.8,
quantity_base: 1.7000000006,
quantity_quote: 59999.8 * 1.7,
quantity_contract: Some(1.7),
};
let text = serde_json::to_string(&order).unwrap();
assert_eq!(text.as_str(), "[59999.8,1.700000001,101999.66,1.7]");
}
#[test]
fn order_deserialize() {
let expected = Order {
price: 59999.8,
quantity_base: 1.7,
quantity_quote: 59999.8 * 1.7,
quantity_contract: Some(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_base, actual.quantity_base);
assert_eq!(expected.quantity_quote, actual.quantity_quote);
assert_eq!(expected.quantity_contract, actual.quantity_contract);
}
}