ouch_model/model/clt/
_04_modify_order.rs1use crate::prelude::*;
2use byteserde_derive::{ByteDeserializeSlice, ByteSerializeStack, ByteSerializedLenOf};
3use serde::{Deserialize, Serialize};
4
5#[derive(ByteSerializeStack, ByteDeserializeSlice, ByteSerializedLenOf, Serialize, Deserialize, PartialEq, Clone, Debug)]
6#[byteserde(endian = "be")]
7pub struct ModifyOrder {
8 #[serde(default, skip_serializing)]
9 packet_type: PacketTypeModifyOrder,
10 user_ref_number: UserRefNumber,
11 side: Side,
12 quantity: Quantity,
13}
14
15pub trait ModifiableOrder {
16 fn user_ref_number(&self) -> UserRefNumber;
17 fn side(&self) -> Side;
18 fn quantity(&self) -> Quantity;
19}
20
21impl<T: ModifiableOrder> From<(&T, Side, Quantity)> for ModifyOrder {
22 fn from(value: (&T, Side, Quantity)) -> Self {
23 let (orig_order, new_side, new_quantity) = (value.0, value.1, value.2);
24 #[cfg(debug_assertions)]
25 {
26 if orig_order.side().is_sell() || orig_order.side().is_sell_short() || orig_order.side().is_sell_short_exempt() {
27 assert!(new_side.is_sell() || new_side.is_sell_short() || new_side.is_sell_short_exempt(), "Side transition from: {}, to: {}, not allowed", orig_order.side(), new_side);
28 } else if orig_order.side().is_buy() {
29 assert!(new_side.is_buy(), "Side transition from: {}, to: {}, not allowed", orig_order.side(), new_side);
30 } else {
31 panic!("Side transition from: {}, to: {}, not allowed", orig_order.side(), new_side);
32 }
33 }
34 Self {
35 packet_type: PacketTypeModifyOrder::default(),
36 user_ref_number: orig_order.user_ref_number(),
37 side: new_side,
38 quantity: new_quantity,
39 }
40 }
41}
42#[cfg(test)]
43mod test {
44 use super::*;
45 use byteserde::prelude::*;
46 use links_core::unittest::setup;
47
48 use log::info;
49 use serde_json::{from_str, to_string};
50 use text_diff::{diff, print_diff};
51
52 #[test]
53 fn test_msg_byteserde() {
54 setup::log::configure_compact(log::LevelFilter::Info);
55 let msg_inp = ModifyOrder::from((&EnterOrder::default(), Side::buy(), 10.into()));
56
57 let ser: ByteSerializerStack<128> = to_serializer_stack(&msg_inp).unwrap();
58 info!("ser: {:#x}", ser);
59
60 let msg_out: ModifyOrder = from_serializer_stack(&ser).unwrap();
61
62 info!("msg_inp: {:?}", msg_inp);
63 info!("msg_out: {:?}", msg_out);
64 assert_eq!(msg_out, msg_inp);
65 }
66
67 #[test]
68 fn test_msg_serde() {
69 setup::log::configure_compact(log::LevelFilter::Info);
70
71 let msg_inp = ModifyOrder::from((&EnterOrder::default(), Side::buy(), 10.into()));
72 let json_out = to_string(&msg_inp).unwrap();
75 let json_exp = r#"{"user_ref_number":1,"side":"BUY","quantity":10}"#;
76 info!("json_out: {}", json_out);
77
78 if matches!(diff(&json_out, json_exp, ","), (dist, _) if dist != 0) {
79 print_diff(&json_out, json_exp, ",");
80 assert_eq!(json_out, json_exp);
81 }
82
83 let msg_out: ModifyOrder = from_str(&json_out).unwrap();
84 assert_eq!(msg_out, msg_inp);
86 }
87}