1use futu_proto::qot_common::Security;
8
9#[derive(Debug, Clone)]
14pub struct ParsedSymbolList {
15 pub securities: Vec<Security>,
17}
18
19impl ParsedSymbolList {
20 pub fn len(&self) -> usize {
22 self.securities.len()
23 }
24
25 pub fn is_empty(&self) -> bool {
27 self.securities.is_empty()
28 }
29
30 pub fn as_slice(&self) -> &[Security] {
32 &self.securities
33 }
34}
35
36pub fn parse_required_symbol_list(securities: &[Security]) -> Result<ParsedSymbolList, String> {
37 let facts = securities_to_core_facts(securities);
38 futu_core::qot_symbol_list::parse_required_symbol_list(&facts)?;
39 Ok(ParsedSymbolList {
40 securities: securities.to_vec(),
41 })
42}
43
44pub fn resolve_required_stock_ids<F>(
45 parsed: &ParsedSymbolList,
46 mut resolver: F,
47) -> Result<Vec<(Security, u64)>, String>
48where
49 F: FnMut(&Security) -> Option<u64>,
50{
51 let facts = securities_to_core_facts(&parsed.securities);
52 let core_parsed = futu_core::qot_symbol_list::parse_required_symbol_list(&facts)?;
53 futu_core::qot_symbol_list::resolve_required_stock_ids(&core_parsed, |sec| {
54 resolver(&Security {
55 market: sec.market,
56 code: sec.code.clone(),
57 })
58 })
59 .map(|resolved| {
60 resolved
61 .into_iter()
62 .map(|(sec, stock_id)| {
63 (
64 Security {
65 market: sec.market,
66 code: sec.code,
67 },
68 stock_id,
69 )
70 })
71 .collect()
72 })
73}
74
75fn securities_to_core_facts(
76 securities: &[Security],
77) -> Vec<futu_core::qot_symbol_list::QotSymbolListSecurity> {
78 securities
79 .iter()
80 .map(|sec| futu_core::qot_symbol_list::QotSymbolListSecurity {
81 market: sec.market,
82 code: sec.code.clone(),
83 })
84 .collect()
85}
86
87#[cfg(test)]
88mod tests;