futucli/cmd/
account_view.rs1use futu_core::account_locator;
2use futu_trd::account::TrdAcc;
3use futu_trd::types::TrdMarket;
4
5pub(super) fn env_label(v: i32) -> &'static str {
6 match v {
7 0 => "simulate",
8 1 => "real",
9 2 => "fund",
10 _ => "?",
11 }
12}
13
14pub(super) fn security_firm_label(v: i32) -> &'static str {
16 match v {
17 1 => "FutuHK",
18 2 => "FutuInc(US)",
19 3 => "FutuSG",
20 4 => "FutuAU",
21 5 => "FutuCA",
22 6 => "FutuMY",
23 7 => "FutuJP",
24 _ => "?",
25 }
26}
27
28pub(super) fn market_label(v: i32) -> &'static str {
29 match v {
30 10 => "SIM_HK_FUTURES",
31 11 => "SIM_US_FUTURES",
32 12 => "SIM_SG_FUTURES",
33 13 => "SIM_JP_FUTURES",
34 0 => "UNKNOWN",
35 _ => futu_trd::market::trd_market_label(v).unwrap_or("?"),
36 }
37}
38
39pub(super) fn market_list_label(markets: &[i32]) -> String {
40 markets
41 .iter()
42 .map(|m| market_label(*m).to_string())
43 .collect::<Vec<_>>()
44 .join(", ")
45}
46
47pub(super) fn account_special_label(label: &str) -> String {
48 match label {
49 "crypto" => "Crypto".to_string(),
50 "equity_incentive" => "Equity Incentive".to_string(),
51 "ipo_route" => "IPO Route".to_string(),
52 "opened_business" => "Business".to_string(),
53 "paper_trade" => "Paper Trade".to_string(),
54 other => other.replace('_', " "),
55 }
56}
57
58pub(super) fn account_market_list_label(a: &TrdAcc) -> String {
59 if a.trd_market_auth_list.is_empty()
60 && let Some(label) = a.acc_label.as_deref()
61 {
62 return account_special_label(label);
63 }
64 market_list_label(&a.trd_market_auth_list)
65}
66
67pub(super) fn acc_type_label(v: i32) -> &'static str {
69 match v {
70 1 => "Cash",
71 2 => "Margin",
72 3 => "Futures",
73 4 => "Option",
74 _ => "?",
75 }
76}
77
78pub(super) fn acc_status_label(v: i32) -> &'static str {
80 match v {
81 0 => "active",
82 1 => "disabled",
83 _ => "?",
84 }
85}
86
87pub(super) fn acc_role_label(v: i32) -> &'static str {
89 match v {
90 0 => "Unknown",
91 1 => "Normal",
92 2 => "Master",
93 3 => "IPO Route",
94 _ => "?",
95 }
96}
97
98pub(super) fn account_display_label(a: &TrdAcc) -> String {
99 if let Some(label) = a.acc_label.as_deref() {
100 return account_special_label(label);
101 }
102 a.acc_role
103 .map(|v| acc_role_label(v).to_string())
104 .unwrap_or_else(|| "-".into())
105}
106
107pub(super) fn visible_card_num(a: &TrdAcc) -> Option<String> {
108 account_locator::visible_card_num(a).map(ToOwned::to_owned)
116}
117
118fn inferred_security_firm_for_markets(markets: &[i32]) -> Option<i32> {
119 if markets.contains(&(TrdMarket::HK as i32)) {
120 Some(1)
121 } else if markets.contains(&(TrdMarket::US as i32)) {
122 Some(2)
123 } else if markets.contains(&(TrdMarket::SG as i32)) {
124 Some(3)
125 } else if markets.contains(&(TrdMarket::AU as i32)) {
126 Some(4)
127 } else if markets.contains(&(TrdMarket::CA as i32)) {
128 Some(5)
129 } else if markets.contains(&(TrdMarket::MY as i32)) {
130 Some(6)
131 } else if markets.contains(&(TrdMarket::JP as i32)) {
132 Some(7)
133 } else {
134 None
135 }
136}
137
138pub(super) fn display_security_firm_label(a: &TrdAcc) -> String {
139 let firm = match a.security_firm {
140 Some(v) if v != 0 => Some(v),
141 _ => inferred_security_firm_for_markets(&a.trd_market_auth_list),
142 };
143 firm.map(security_firm_label).unwrap_or("-").to_string()
144}