futu_cache/trd_cache/
trade_write_lookup.rs1use super::{CachedOrderSnapshot, ResolveOrderError, TrdCache};
2use futu_domain_trade_account::{
3 TradeWriteOrderIdCandidateFacts, TradeWriteOrderIdExCandidateFacts,
4 TradeWriteOrderIdExCandidateMatch, TradeWriteOrderIdSnapshotDecision,
5 TradeWriteOrderLookupRequest, TradeWriteOrderLookupRoute, TradeWriteSnapshotBackendIdPatch,
6 classify_trade_write_order_id_ex_candidate, plan_trade_write_order_id_snapshot,
7 plan_trade_write_order_lookup_route, plan_trade_write_snapshot_backend_id_patch,
8 trade_write_order_id_candidate_matches,
9};
10
11impl TrdCache {
12 pub fn find_order_for_trade_write(
20 &self,
21 acc_id: u64,
22 order_id: u64,
23 order_id_ex: Option<&str>,
24 ) -> Result<CachedOrderSnapshot, ResolveOrderError> {
25 match plan_trade_write_order_lookup_route(TradeWriteOrderLookupRequest {
26 order_id,
27 order_id_ex,
28 }) {
29 TradeWriteOrderLookupRoute::ByOrderIdEx { order_id_ex } => {
30 self.find_order_for_trade_write_by_order_id_ex(acc_id, order_id_ex)
31 }
32 TradeWriteOrderLookupRoute::ByOrderId { order_id } => {
33 self.find_order_for_trade_write_by_hash(acc_id, order_id)
34 }
35 TradeWriteOrderLookupRoute::RejectInvalidInput => Err(ResolveOrderError::InvalidInput),
36 }
37 }
38
39 fn find_order_for_trade_write_by_order_id_ex(
40 &self,
41 acc_id: u64,
42 order_id_ex: &str,
43 ) -> Result<CachedOrderSnapshot, ResolveOrderError> {
44 let orders = self
45 .orders
46 .get(&acc_id)
47 .ok_or(ResolveOrderError::CacheMiss)?;
48 if let Some(order) = orders.iter().find(|order| {
49 matches!(
50 classify_trade_write_order_id_ex_candidate(TradeWriteOrderIdExCandidateFacts {
51 backend_order_id: &order.backend_order_id,
52 order_id_ex: &order.order_id_ex,
53 requested_order_id_ex: order_id_ex,
54 }),
55 TradeWriteOrderIdExCandidateMatch::BackendOrderId
56 )
57 }) {
58 return Ok(CachedOrderSnapshot::from_order(order));
59 }
60
61 if let Some(order) = orders.iter().find(|order| {
62 matches!(
63 classify_trade_write_order_id_ex_candidate(TradeWriteOrderIdExCandidateFacts {
64 backend_order_id: &order.backend_order_id,
65 order_id_ex: &order.order_id_ex,
66 requested_order_id_ex: order_id_ex,
67 }),
68 TradeWriteOrderIdExCandidateMatch::OrderIdExField
69 )
70 }) {
71 let mut snap = CachedOrderSnapshot::from_order(order);
72 if matches!(
73 plan_trade_write_snapshot_backend_id_patch(&snap.backend_order_id),
74 TradeWriteSnapshotBackendIdPatch::UseRequestedOrderIdEx
75 ) {
76 snap.backend_order_id = order_id_ex.to_string();
77 }
78 return Ok(snap);
79 }
80
81 Err(ResolveOrderError::CacheMiss)
82 }
83
84 fn find_order_for_trade_write_by_hash(
85 &self,
86 acc_id: u64,
87 order_id: u64,
88 ) -> Result<CachedOrderSnapshot, ResolveOrderError> {
89 let orders = self
90 .orders
91 .get(&acc_id)
92 .ok_or(ResolveOrderError::CacheMiss)?;
93 let order = orders
94 .iter()
95 .find(|order| {
96 trade_write_order_id_candidate_matches(TradeWriteOrderIdCandidateFacts {
97 cached_order_id: order.order_id,
98 requested_order_id: order_id,
99 })
100 })
101 .ok_or(ResolveOrderError::CacheMiss)?;
102 match plan_trade_write_order_id_snapshot(&order.backend_order_id) {
103 TradeWriteOrderIdSnapshotDecision::Accept => Ok(CachedOrderSnapshot::from_order(order)),
104 TradeWriteOrderIdSnapshotDecision::RejectMissingBackendId => {
105 Err(ResolveOrderError::MissingBackendId)
106 }
107 }
108 }
109}