nautilus_model/events/order/spec/
pending_cancel.rs1use nautilus_core::{UUID4, UnixNanos};
17
18use crate::{
19 events::OrderPendingCancel,
20 identifiers::{AccountId, ClientOrderId, InstrumentId, StrategyId, TraderId, VenueOrderId},
21 stubs::{TestDefault, test_uuid},
22};
23
24#[derive(Debug, Clone, bon::Builder)]
30#[builder(finish_fn = into_spec)]
31pub struct OrderPendingCancelSpec {
32 #[builder(default = TraderId::test_default())]
33 pub trader_id: TraderId,
34 #[builder(default = StrategyId::test_default())]
35 pub strategy_id: StrategyId,
36 #[builder(default = InstrumentId::test_default())]
37 pub instrument_id: InstrumentId,
38 #[builder(default = ClientOrderId::test_default())]
39 pub client_order_id: ClientOrderId,
40 #[builder(default = AccountId::test_default())]
41 pub account_id: AccountId,
42 #[builder(default = test_uuid())]
43 pub event_id: UUID4,
44 #[builder(default = UnixNanos::default())]
45 pub ts_event: UnixNanos,
46 #[builder(default = UnixNanos::default())]
47 pub ts_init: UnixNanos,
48 #[builder(default = false)]
49 pub reconciliation: bool,
50 pub venue_order_id: Option<VenueOrderId>,
51}
52
53impl<S: order_pending_cancel_spec_builder::IsComplete> OrderPendingCancelSpecBuilder<S> {
54 #[must_use]
56 pub fn build(self) -> OrderPendingCancel {
57 let spec = self.into_spec();
58 OrderPendingCancel::new(
59 spec.trader_id,
60 spec.strategy_id,
61 spec.instrument_id,
62 spec.client_order_id,
63 spec.account_id,
64 spec.event_id,
65 spec.ts_event,
66 spec.ts_init,
67 spec.reconciliation,
68 spec.venue_order_id,
69 )
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use rstest::rstest;
76
77 use super::*;
78 use crate::stubs::reset_test_uuid_rng;
79
80 #[rstest]
81 fn defaults_are_sensible() {
82 let event = OrderPendingCancelSpec::builder().build();
85 assert_eq!(event.trader_id, TraderId::test_default());
86 assert_eq!(event.strategy_id, StrategyId::test_default());
87 assert_eq!(event.instrument_id, InstrumentId::test_default());
88 assert_eq!(event.client_order_id, ClientOrderId::test_default());
89 assert_eq!(event.account_id, AccountId::test_default());
90 assert_eq!(event.ts_event, UnixNanos::default());
91 assert_eq!(event.ts_init, UnixNanos::default());
92 assert_eq!(event.reconciliation, 0);
93 assert_eq!(event.venue_order_id, None);
94 }
95
96 #[rstest]
97 fn overrides_apply_through_constructor() {
98 let event = OrderPendingCancelSpec::builder()
99 .venue_order_id(VenueOrderId::from("V-1"))
100 .reconciliation(true)
101 .build();
102
103 assert_eq!(event.venue_order_id, Some(VenueOrderId::from("V-1")));
104 assert_eq!(event.reconciliation, 1);
106 assert_eq!(event.trader_id, TraderId::test_default());
107 }
108
109 #[rstest]
110 fn event_ids_are_unique_within_a_run() {
111 reset_test_uuid_rng();
112 let a = OrderPendingCancelSpec::builder().build();
113 let b = OrderPendingCancelSpec::builder().build();
114 let c = OrderPendingCancelSpec::builder().build();
115 assert_ne!(a.event_id, b.event_id);
116 assert_ne!(b.event_id, c.event_id);
117 assert_ne!(a.event_id, c.event_id);
118 }
119
120 #[rstest]
121 fn event_id_sequence_is_reproducible() {
122 reset_test_uuid_rng();
124 let first_run: Vec<_> = (0..3)
125 .map(|_| OrderPendingCancelSpec::builder().build().event_id)
126 .collect();
127
128 reset_test_uuid_rng();
129 let second_run: Vec<_> = (0..3)
130 .map(|_| OrderPendingCancelSpec::builder().build().event_id)
131 .collect();
132
133 assert_eq!(first_run, second_run);
134 }
135}