1use std::str::FromStr;
17
18use indexmap::IndexMap;
19use nautilus_core::{UUID4, UnixNanos};
20use nautilus_model::{
21 enums::{
22 ContingencyType, LiquiditySide, OrderSide, OrderStatus, OrderType, TimeInForce, TriggerType,
23 },
24 events::{
25 OrderAccepted, OrderCancelRejected, OrderCanceled, OrderDenied, OrderEmulated,
26 OrderEventAny, OrderExpired, OrderFilled, OrderInitialized, OrderModifyRejected,
27 OrderPendingCancel, OrderPendingUpdate, OrderRejected, OrderReleased, OrderSnapshot,
28 OrderSubmitted, OrderTriggered, OrderUpdated,
29 },
30 identifiers::{
31 AccountId, ClientOrderId, ExecAlgorithmId, InstrumentId, OrderListId, PositionId,
32 StrategyId, TradeId, TraderId, VenueOrderId,
33 },
34 types::{Currency, Money, Price, Quantity},
35};
36use rust_decimal::Decimal;
37use sqlx::{FromRow, Row, postgres::PgRow};
38use ustr::Ustr;
39
40use crate::sql::models::enums::TrailingOffsetTypeModel;
41
42#[derive(Debug)]
43pub struct OrderEventAnyModel(pub OrderEventAny);
44
45#[derive(Debug)]
46pub struct OrderAcceptedModel(pub OrderAccepted);
47
48#[derive(Debug)]
49pub struct OrderCancelRejectedModel(pub OrderCancelRejected);
50
51#[derive(Debug)]
52pub struct OrderCanceledModel(pub OrderCanceled);
53
54#[derive(Debug)]
55pub struct OrderDeniedModel(pub OrderDenied);
56
57#[derive(Debug)]
58pub struct OrderEmulatedModel(pub OrderEmulated);
59
60#[derive(Debug)]
61pub struct OrderExpiredModel(pub OrderExpired);
62
63#[derive(Debug)]
64pub struct OrderFilledModel(pub OrderFilled);
65
66#[derive(Debug)]
67pub struct OrderInitializedModel(pub OrderInitialized);
68
69#[derive(Debug)]
70pub struct OrderModifyRejectedModel(pub OrderModifyRejected);
71
72#[derive(Debug)]
73pub struct OrderPendingCancelModel(pub OrderPendingCancel);
74
75#[derive(Debug)]
76pub struct OrderPendingUpdateModel(pub OrderPendingUpdate);
77
78#[derive(Debug)]
79pub struct OrderRejectedModel(pub OrderRejected);
80
81#[derive(Debug)]
82pub struct OrderReleasedModel(pub OrderReleased);
83
84#[derive(Debug)]
85pub struct OrderSubmittedModel(pub OrderSubmitted);
86
87#[derive(Debug)]
88pub struct OrderTriggeredModel(pub OrderTriggered);
89
90#[derive(Debug)]
91pub struct OrderUpdatedModel(pub OrderUpdated);
92
93#[derive(Debug)]
94pub struct OrderSnapshotModel(pub OrderSnapshot);
95
96impl<'r> FromRow<'r, PgRow> for OrderEventAnyModel {
97 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
98 let kind = row.get::<String, _>("kind");
99 if kind == "OrderAccepted" {
100 let model = OrderAcceptedModel::from_row(row)?;
101 Ok(Self(OrderEventAny::Accepted(model.0)))
102 } else if kind == "OrderCancelRejected" {
103 let model = OrderCancelRejectedModel::from_row(row)?;
104 Ok(Self(OrderEventAny::CancelRejected(model.0)))
105 } else if kind == "OrderCanceled" {
106 let model = OrderCanceledModel::from_row(row)?;
107 Ok(Self(OrderEventAny::Canceled(model.0)))
108 } else if kind == "OrderDenied" {
109 let model = OrderDeniedModel::from_row(row)?;
110 Ok(Self(OrderEventAny::Denied(model.0)))
111 } else if kind == "OrderEmulated" {
112 let model = OrderEmulatedModel::from_row(row)?;
113 Ok(Self(OrderEventAny::Emulated(model.0)))
114 } else if kind == "OrderExpired" {
115 let model = OrderExpiredModel::from_row(row)?;
116 Ok(Self(OrderEventAny::Expired(model.0)))
117 } else if kind == "OrderFilled" {
118 let model = OrderFilledModel::from_row(row)?;
119 Ok(Self(OrderEventAny::Filled(model.0)))
120 } else if kind == "OrderInitialized" {
121 let model = OrderInitializedModel::from_row(row)?;
122 Ok(Self(OrderEventAny::Initialized(model.0)))
123 } else if kind == "OrderModifyRejected" {
124 let model = OrderModifyRejectedModel::from_row(row)?;
125 Ok(Self(OrderEventAny::ModifyRejected(model.0)))
126 } else if kind == "OrderPendingCancel" {
127 let model = OrderPendingCancelModel::from_row(row)?;
128 Ok(Self(OrderEventAny::PendingCancel(model.0)))
129 } else if kind == "OrderPendingUpdate" {
130 let model = OrderPendingUpdateModel::from_row(row)?;
131 Ok(Self(OrderEventAny::PendingUpdate(model.0)))
132 } else if kind == "OrderRejected" {
133 let model = OrderRejectedModel::from_row(row)?;
134 Ok(Self(OrderEventAny::Rejected(model.0)))
135 } else if kind == "OrderReleased" {
136 let model = OrderReleasedModel::from_row(row)?;
137 Ok(Self(OrderEventAny::Released(model.0)))
138 } else if kind == "OrderSubmitted" {
139 let model = OrderSubmittedModel::from_row(row)?;
140 Ok(Self(OrderEventAny::Submitted(model.0)))
141 } else if kind == "OrderTriggered" {
142 let model = OrderTriggeredModel::from_row(row)?;
143 Ok(Self(OrderEventAny::Triggered(model.0)))
144 } else if kind == "OrderUpdated" {
145 let model = OrderUpdatedModel::from_row(row)?;
146 Ok(Self(OrderEventAny::Updated(model.0)))
147 } else {
148 panic!("Unknown order event kind: {kind} in Postgres transformation")
149 }
150 }
151}
152
153impl<'r> FromRow<'r, PgRow> for OrderInitializedModel {
154 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
155 let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
156 let client_order_id = row
157 .try_get::<&str, _>("client_order_id")
158 .map(ClientOrderId::from)?;
159 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
160 let strategy_id = row
161 .try_get::<&str, _>("strategy_id")
162 .map(StrategyId::from)?;
163 let instrument_id = row
164 .try_get::<&str, _>("instrument_id")
165 .map(InstrumentId::from)?;
166 let order_type = row
167 .try_get::<&str, _>("order_type")
168 .map(|x| OrderType::from_str(x).unwrap())?;
169 let order_side = row
170 .try_get::<&str, _>("order_side")
171 .map(|x| OrderSide::from_str(x).unwrap())?;
172 let quantity = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
173 let time_in_force = row
174 .try_get::<&str, _>("time_in_force")
175 .map(|x| TimeInForce::from_str(x).unwrap())?;
176 let post_only = row.try_get::<bool, _>("post_only")?;
177 let reduce_only = row.try_get::<bool, _>("reduce_only")?;
178 let quote_quantity = row.try_get::<bool, _>("quote_quantity")?;
179 let reconciliation = row.try_get::<bool, _>("reconciliation")?;
180 let ts_event = row.try_get::<String, _>("ts_event").map(UnixNanos::from)?;
181 let ts_init = row.try_get::<String, _>("ts_init").map(UnixNanos::from)?;
182 let price = row
183 .try_get::<Option<&str>, _>("price")
184 .ok()
185 .and_then(|x| x.map(Price::from));
186 let trigger_price = row
187 .try_get::<Option<&str>, _>("trigger_price")
188 .ok()
189 .and_then(|x| x.map(Price::from));
190 let trigger_type = row
191 .try_get::<Option<&str>, _>("trigger_type")
192 .ok()
193 .and_then(|x| x.map(|x| TriggerType::from_str(x).unwrap()));
194 let limit_offset = row
195 .try_get::<Option<&str>, _>("limit_offset")
196 .ok()
197 .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
198 let trailing_offset = row
199 .try_get::<Option<&str>, _>("trailing_offset")
200 .ok()
201 .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
202 let trailing_offset_type = row
203 .try_get::<Option<TrailingOffsetTypeModel>, _>("trailing_offset_type")
204 .ok()
205 .and_then(|x| x.map(|x| x.0));
206 let expire_time = row
207 .try_get::<Option<&str>, _>("expire_time")
208 .ok()
209 .and_then(|x| x.map(UnixNanos::from));
210 let display_qty = row
211 .try_get::<Option<&str>, _>("display_qty")
212 .ok()
213 .and_then(|x| x.map(Quantity::from));
214 let emulation_trigger = row
215 .try_get::<Option<&str>, _>("emulation_trigger")
216 .ok()
217 .and_then(|x| x.map(|x| TriggerType::from_str(x).unwrap()));
218 let trigger_instrument_id = row
219 .try_get::<Option<&str>, _>("trigger_instrument_id")
220 .ok()
221 .and_then(|x| x.map(InstrumentId::from));
222 let contingency_type = row
223 .try_get::<Option<&str>, _>("contingency_type")
224 .ok()
225 .and_then(|x| x.map(|x| ContingencyType::from_str(x).unwrap()));
226 let order_list_id = row
227 .try_get::<Option<&str>, _>("order_list_id")
228 .ok()
229 .and_then(|x| x.map(OrderListId::from));
230 let linked_order_ids = row
231 .try_get::<Vec<String>, _>("linked_order_ids")
232 .ok()
233 .map(|x| x.iter().map(|x| ClientOrderId::from(x.as_str())).collect());
234 let parent_order_id = row
235 .try_get::<Option<&str>, _>("parent_order_id")
236 .ok()
237 .and_then(|x| x.map(ClientOrderId::from));
238 let exec_algorithm_id = row
239 .try_get::<Option<&str>, _>("exec_algorithm_id")
240 .ok()
241 .and_then(|x| x.map(ExecAlgorithmId::from));
242 let exec_algorithm_params: Option<IndexMap<Ustr, Ustr>> = row
243 .try_get::<Option<serde_json::Value>, _>("exec_algorithm_params")
244 .ok()
245 .and_then(|x| x.map(|x| serde_json::from_value::<IndexMap<String, String>>(x).unwrap()))
246 .map(|x| {
247 x.into_iter()
248 .map(|(k, v)| (Ustr::from(k.as_str()), Ustr::from(v.as_str())))
249 .collect()
250 });
251 let exec_spawn_id = row
252 .try_get::<Option<&str>, _>("exec_spawn_id")
253 .ok()
254 .and_then(|x| x.map(ClientOrderId::from));
255 let tags: Option<Vec<Ustr>> = row
256 .try_get::<Option<serde_json::Value>, _>("tags")
257 .ok()
258 .and_then(|x| x.map(|x| serde_json::from_value::<Vec<String>>(x).unwrap()))
259 .map(|x| x.into_iter().map(|x| Ustr::from(x.as_str())).collect());
260 let order_event = OrderInitialized::new(
261 trader_id,
262 strategy_id,
263 instrument_id,
264 client_order_id,
265 order_side,
266 order_type,
267 quantity,
268 time_in_force,
269 post_only,
270 reduce_only,
271 quote_quantity,
272 reconciliation,
273 event_id,
274 ts_event,
275 ts_init,
276 price,
277 trigger_price,
278 trigger_type,
279 limit_offset,
280 trailing_offset,
281 trailing_offset_type,
282 expire_time,
283 display_qty,
284 emulation_trigger,
285 trigger_instrument_id,
286 contingency_type,
287 order_list_id,
288 linked_order_ids,
289 parent_order_id,
290 exec_algorithm_id,
291 exec_algorithm_params,
292 exec_spawn_id,
293 tags,
294 );
295 Ok(Self(order_event))
296 }
297}
298
299impl<'r> FromRow<'r, PgRow> for OrderAcceptedModel {
300 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
301 let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
302 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
303 let strategy_id = row
304 .try_get::<&str, _>("strategy_id")
305 .map(StrategyId::from)?;
306 let instrument_id = row
307 .try_get::<&str, _>("instrument_id")
308 .map(InstrumentId::from)?;
309 let client_order_id = row
310 .try_get::<&str, _>("client_order_id")
311 .map(ClientOrderId::from)?;
312 let venue_order_id = row
313 .try_get::<&str, _>("venue_order_id")
314 .map(VenueOrderId::from)?;
315 let account_id = row.try_get::<&str, _>("account_id").map(AccountId::from)?;
316 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
317 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
318 let order_event = OrderAccepted::new(
319 trader_id,
320 strategy_id,
321 instrument_id,
322 client_order_id,
323 venue_order_id,
324 account_id,
325 event_id,
326 ts_event,
327 ts_init,
328 false,
329 );
330 Ok(Self(order_event))
331 }
332}
333
334impl<'r> FromRow<'r, PgRow> for OrderCancelRejectedModel {
335 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
336 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
337 let strategy_id = row
338 .try_get::<&str, _>("strategy_id")
339 .map(StrategyId::from)?;
340 let instrument_id = row
341 .try_get::<&str, _>("instrument_id")
342 .map(InstrumentId::from)?;
343 let client_order_id = row
344 .try_get::<&str, _>("client_order_id")
345 .map(ClientOrderId::from)?;
346 let reason = row.try_get::<&str, _>("reason").map(Ustr::from)?;
347 let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
348 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
349 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
350 let reconciliation = row.try_get::<bool, _>("reconciliation")?;
351 let venue_order_id = row
352 .try_get::<Option<&str>, _>("venue_order_id")?
353 .map(Into::into);
354 let account_id = row
355 .try_get::<Option<&str>, _>("account_id")?
356 .map(Into::into);
357 let order_event = OrderCancelRejected::new(
358 trader_id,
359 strategy_id,
360 instrument_id,
361 client_order_id,
362 reason,
363 event_id,
364 ts_event,
365 ts_init,
366 reconciliation,
367 venue_order_id,
368 account_id,
369 );
370 Ok(Self(order_event))
371 }
372}
373
374impl<'r> FromRow<'r, PgRow> for OrderCanceledModel {
375 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
376 todo!()
377 }
378}
379
380impl<'r> FromRow<'r, PgRow> for OrderDeniedModel {
381 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
382 todo!()
383 }
384}
385
386impl<'r> FromRow<'r, PgRow> for OrderEmulatedModel {
387 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
388 todo!()
389 }
390}
391
392impl<'r> FromRow<'r, PgRow> for OrderExpiredModel {
393 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
394 todo!()
395 }
396}
397
398impl<'r> FromRow<'r, PgRow> for OrderFilledModel {
399 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
400 let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
401 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
402 let strategy_id = row
403 .try_get::<&str, _>("strategy_id")
404 .map(StrategyId::from)?;
405 let instrument_id = row
406 .try_get::<&str, _>("instrument_id")
407 .map(InstrumentId::from)?;
408 let client_order_id = row
409 .try_get::<&str, _>("client_order_id")
410 .map(ClientOrderId::from)?;
411 let venue_order_id = row
412 .try_get::<&str, _>("venue_order_id")
413 .map(VenueOrderId::from)?;
414 let account_id = row.try_get::<&str, _>("account_id").map(AccountId::from)?;
415 let trade_id = row.try_get::<&str, _>("trade_id").map(TradeId::from)?;
416 let order_side = row
417 .try_get::<&str, _>("order_side")
418 .map(|x| OrderSide::from_str(x).unwrap())?;
419 let order_type = row
420 .try_get::<&str, _>("order_type")
421 .map(|x| OrderType::from_str(x).unwrap())?;
422 let last_px = row.try_get::<&str, _>("last_px").map(Price::from)?;
423 let last_qty = row.try_get::<&str, _>("last_qty").map(Quantity::from)?;
424 let currency = row.try_get::<&str, _>("currency").map(Currency::from)?;
425 let liquidity_side = row
426 .try_get::<&str, _>("liquidity_side")
427 .map(|x| LiquiditySide::from_str(x).unwrap())?;
428 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
429 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
430 let position_id = row
431 .try_get::<Option<&str>, _>("position_id")
432 .map(|x| x.map(PositionId::from))?;
433 let commission = row
434 .try_get::<Option<&str>, _>("commission")
435 .map(|x| x.map(|x| Money::from_str(x).unwrap()))?;
436 let order_event = OrderFilled::new(
437 trader_id,
438 strategy_id,
439 instrument_id,
440 client_order_id,
441 venue_order_id,
442 account_id,
443 trade_id,
444 order_side,
445 order_type,
446 last_qty,
447 last_px,
448 currency,
449 liquidity_side,
450 event_id,
451 ts_event,
452 ts_init,
453 false,
454 position_id,
455 commission,
456 );
457 Ok(Self(order_event))
458 }
459}
460
461impl<'r> FromRow<'r, PgRow> for OrderModifyRejectedModel {
462 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
463 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
464 let strategy_id = row
465 .try_get::<&str, _>("strategy_id")
466 .map(StrategyId::from)?;
467 let instrument_id = row
468 .try_get::<&str, _>("instrument_id")
469 .map(InstrumentId::from)?;
470 let client_order_id = row
471 .try_get::<&str, _>("client_order_id")
472 .map(ClientOrderId::from)?;
473 let reason = row.try_get::<&str, _>("reason").map(Ustr::from)?;
474 let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
475 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
476 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
477 let reconciliation = row.try_get::<bool, _>("reconciliation")?;
478 let venue_order_id = row
479 .try_get::<Option<&str>, _>("venue_order_id")?
480 .map(Into::into);
481 let account_id = row
482 .try_get::<Option<&str>, _>("account_id")?
483 .map(Into::into);
484 let order_event = OrderModifyRejected::new(
485 trader_id,
486 strategy_id,
487 instrument_id,
488 client_order_id,
489 reason,
490 event_id,
491 ts_event,
492 ts_init,
493 reconciliation,
494 venue_order_id,
495 account_id,
496 );
497 Ok(Self(order_event))
498 }
499}
500
501impl<'r> FromRow<'r, PgRow> for OrderPendingCancelModel {
502 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
503 todo!()
504 }
505}
506
507impl<'r> FromRow<'r, PgRow> for OrderPendingUpdateModel {
508 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
509 todo!()
510 }
511}
512
513impl<'r> FromRow<'r, PgRow> for OrderRejectedModel {
514 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
515 todo!()
516 }
517}
518
519impl<'r> FromRow<'r, PgRow> for OrderReleasedModel {
520 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
521 todo!()
522 }
523}
524
525impl<'r> FromRow<'r, PgRow> for OrderSubmittedModel {
526 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
527 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
528 let strategy_id = row
529 .try_get::<&str, _>("strategy_id")
530 .map(StrategyId::from)?;
531 let instrument_id = row
532 .try_get::<&str, _>("instrument_id")
533 .map(InstrumentId::from)?;
534 let client_order_id = row
535 .try_get::<&str, _>("client_order_id")
536 .map(ClientOrderId::from)?;
537 let account_id = row.try_get::<&str, _>("account_id").map(AccountId::from)?;
538 let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
539 let ts_event = row
540 .try_get::<String, _>("ts_event")
541 .map(|res| UnixNanos::from(res.as_str()))?;
542 let ts_init = row
543 .try_get::<String, _>("ts_init")
544 .map(|res| UnixNanos::from(res.as_str()))?;
545 let order_event = OrderSubmitted::new(
546 trader_id,
547 strategy_id,
548 instrument_id,
549 client_order_id,
550 account_id,
551 event_id,
552 ts_event,
553 ts_init,
554 );
555 Ok(Self(order_event))
556 }
557}
558
559impl<'r> FromRow<'r, PgRow> for OrderTriggeredModel {
560 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
561 todo!()
562 }
563}
564
565impl<'r> FromRow<'r, PgRow> for OrderUpdatedModel {
566 fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
567 todo!()
568 }
569}
570
571impl<'r> FromRow<'r, PgRow> for OrderSnapshotModel {
572 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
573 let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
574 let strategy_id = row
575 .try_get::<&str, _>("strategy_id")
576 .map(StrategyId::from)?;
577 let instrument_id = row
578 .try_get::<&str, _>("instrument_id")
579 .map(InstrumentId::from)?;
580 let client_order_id = row
581 .try_get::<&str, _>("client_order_id")
582 .map(ClientOrderId::from)?;
583 let venue_order_id = row
584 .try_get::<Option<&str>, _>("venue_order_id")
585 .ok()
586 .and_then(|x| x.map(VenueOrderId::from));
587 let position_id = row
588 .try_get::<Option<&str>, _>("position_id")
589 .ok()
590 .and_then(|x| x.map(PositionId::from));
591 let account_id = row
592 .try_get::<Option<&str>, _>("account_id")
593 .ok()
594 .and_then(|x| x.map(AccountId::from));
595 let last_trade_id = row
596 .try_get::<Option<&str>, _>("last_trade_id")
597 .ok()
598 .and_then(|x| x.map(TradeId::from));
599 let order_type = row
600 .try_get::<&str, _>("order_type")
601 .map(|x| OrderType::from_str(x).expect("Invalid `OrderType`"))?;
602 let order_side = row
603 .try_get::<&str, _>("order_side")
604 .map(|x| OrderSide::from_str(x).expect("Invalid `OrderSide`"))?;
605 let quantity = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
606 let price = row
607 .try_get::<Option<&str>, _>("price")
608 .ok()
609 .and_then(|x| x.map(Price::from));
610 let trigger_price = row
611 .try_get::<Option<&str>, _>("trigger_price")
612 .ok()
613 .and_then(|x| x.map(Price::from));
614 let trigger_type = row
615 .try_get::<Option<&str>, _>("trigger_type")
616 .ok()
617 .and_then(|x| x.map(|x| TriggerType::from_str(x).expect("Invalid `TriggerType`")));
618 let limit_offset = row
619 .try_get::<Option<&str>, _>("limit_offset")
620 .ok()
621 .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
622 let trailing_offset = row
623 .try_get::<Option<&str>, _>("trailing_offset")
624 .ok()
625 .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
626 let trailing_offset_type = row
627 .try_get::<Option<TrailingOffsetTypeModel>, _>("trailing_offset_type")
628 .ok()
629 .and_then(|x| x.map(|x| x.0));
630 let time_in_force = row
631 .try_get::<&str, _>("time_in_force")
632 .map(|x| TimeInForce::from_str(x).expect("Invalid `TimeInForce`"))?;
633 let expire_time = row
634 .try_get::<Option<&str>, _>("expire_time")
635 .ok()
636 .and_then(|x| x.map(UnixNanos::from));
637 let filled_qty = row.try_get::<&str, _>("filled_qty").map(Quantity::from)?;
638 let liquidity_side = row
639 .try_get::<Option<&str>, _>("liquidity_side")
640 .ok()
641 .and_then(|x| x.map(|x| LiquiditySide::from_str(x).expect("Invalid `LiquiditySide`")));
642 let avg_px = row.try_get::<Option<f64>, _>("avg_px").ok().flatten();
643 let slippage = row.try_get::<Option<f64>, _>("slippage").ok().flatten();
644 let commissions = row
645 .try_get::<Option<Vec<String>>, _>("commissions")?
646 .map_or_else(Vec::new, |c| {
647 c.into_iter().map(|s| Money::from(&s)).collect()
648 });
649 let status = row
650 .try_get::<&str, _>("status")
651 .map(|x| OrderStatus::from_str(x).expect("Invalid `OrderStatus`"))?;
652 let is_post_only = row.try_get::<bool, _>("is_post_only")?;
653 let is_reduce_only = row.try_get::<bool, _>("is_reduce_only")?;
654 let is_quote_quantity = row.try_get::<bool, _>("is_quote_quantity")?;
655 let display_qty = row
656 .try_get::<Option<&str>, _>("display_qty")
657 .ok()
658 .and_then(|x| x.map(Quantity::from));
659 let emulation_trigger = row
660 .try_get::<Option<&str>, _>("emulation_trigger")
661 .ok()
662 .and_then(|x| x.map(|x| TriggerType::from_str(x).expect("Invalid `TriggerType`")));
663 let trigger_instrument_id = row
664 .try_get::<Option<&str>, _>("trigger_instrument_id")
665 .ok()
666 .and_then(|x| x.map(InstrumentId::from));
667 let contingency_type = row
668 .try_get::<Option<&str>, _>("contingency_type")
669 .ok()
670 .and_then(|x| {
671 x.map(|x| ContingencyType::from_str(x).expect("Invalid `ContingencyType`"))
672 });
673 let order_list_id = row
674 .try_get::<Option<&str>, _>("order_list_id")
675 .ok()
676 .and_then(|x| x.map(OrderListId::from));
677 let linked_order_ids = row
678 .try_get::<Option<Vec<String>>, _>("linked_order_ids")
679 .ok()
680 .and_then(|ids| ids.map(|ids| ids.into_iter().map(ClientOrderId::from).collect()));
681 let parent_order_id = row
682 .try_get::<Option<&str>, _>("parent_order_id")
683 .ok()
684 .and_then(|x| x.map(ClientOrderId::from));
685 let exec_algorithm_id = row
686 .try_get::<Option<&str>, _>("exec_algorithm_id")
687 .ok()
688 .and_then(|x| x.map(ExecAlgorithmId::from));
689 let exec_algorithm_params: Option<IndexMap<Ustr, Ustr>> = row
690 .try_get::<Option<serde_json::Value>, _>("exec_algorithm_params")
691 .ok()
692 .and_then(|x| {
693 x.map(|x| {
694 serde_json::from_value::<IndexMap<String, String>>(x)
695 .expect("Invalid exec algorithm params")
696 })
697 })
698 .map(|x| {
699 x.into_iter()
700 .map(|(k, v)| (Ustr::from(k.as_str()), Ustr::from(v.as_str())))
701 .collect()
702 });
703 let exec_spawn_id = row
704 .try_get::<Option<&str>, _>("exec_spawn_id")
705 .ok()
706 .and_then(|x| x.map(ClientOrderId::from));
707 let tags = row
708 .try_get::<Option<serde_json::Value>, _>("tags")
709 .ok()
710 .flatten()
711 .and_then(|tags_value| {
712 serde_json::from_value::<Vec<String>>(tags_value)
713 .ok()
714 .map(|vec| {
715 vec.into_iter()
716 .map(|tag| Ustr::from(tag.as_str()))
717 .collect::<Vec<Ustr>>()
718 })
719 });
720 let init_id = row.try_get::<&str, _>("init_id").map(UUID4::from)?;
721 let ts_init = row.try_get::<String, _>("ts_init").map(UnixNanos::from)?;
722 let ts_last = row.try_get::<String, _>("ts_last").map(UnixNanos::from)?;
723
724 let snapshot = OrderSnapshot {
725 trader_id,
726 strategy_id,
727 instrument_id,
728 client_order_id,
729 venue_order_id,
730 position_id,
731 account_id,
732 last_trade_id,
733 order_type,
734 order_side,
735 quantity,
736 price,
737 trigger_price,
738 trigger_type,
739 limit_offset,
740 trailing_offset,
741 trailing_offset_type,
742 time_in_force,
743 expire_time,
744 filled_qty,
745 liquidity_side,
746 avg_px,
747 slippage,
748 commissions,
749 status,
750 is_post_only,
751 is_reduce_only,
752 is_quote_quantity,
753 display_qty,
754 emulation_trigger,
755 trigger_instrument_id,
756 contingency_type,
757 order_list_id,
758 linked_order_ids,
759 parent_order_id,
760 exec_algorithm_id,
761 exec_algorithm_params,
762 exec_spawn_id,
763 tags,
764 init_id,
765 ts_init,
766 ts_last,
767 };
768
769 Ok(Self(snapshot))
770 }
771}