1use serde::{Deserialize, Serialize};
2use serde::de;
3use std::fmt;
4
5#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
7pub enum Api {
8 StockBasic,
9 FundBasic,
10 FundDaily,
11 FundPortfolio,
12 Daily,
13 DailyBasic,
14 MoneyflowMktDc,
15 Weekly,
16 Monthly,
17 IndexDaily,
18 IndexWeekly,
19 IndexMonthly,
20 TradeCal,
21 Margin,
22 StockCompany,
23 MarginDetail,
24 StkHoldernumber,
25 ThsIndex,
26 ThsMember,
27 ThsDaily,
28 ThsHot,
29 FinaMainbz,
30 FinaMainbzVip,
31 FinaIndicator,
32 Balancesheet,
33 Income,
34 Cashflow,
35 IndexBasic,
36 IndexDailyBasic,
37 Moneyflow,
38 MoneyflowIndustryThs,
39
40 UsBasic,
41 UsDaily,
42 Custom(String), }
44
45const API_STOCK_BASIC: &str = "stock_basic";
46const API_FUND_BASIC: &str = "fund_basic";
47const API_FUND_DAILY: &str = "fund_daily";
48const API_FUND_PORTFOLIO: &str = "fund_portfolio";
49const API_DAILY: &str = "daily";
50const API_DAILY_BASIC: &str = "daily_basic";
51const API_MONEYFLOW_MKT_DC: &str = "moneyflow_mkt_dc";
52const API_WEEKLY: &str = "weekly";
53const API_MONTHLY: &str = "monthly";
54const API_INDEX_DAILY: &str = "index_daily";
55const API_INDEX_WEEKLY: &str = "index_weekly";
56const API_INDEX_MONTHLY: &str = "index_monthly";
57const API_TRADE_CAL: &str = "trade_cal";
58const API_MARGIN: &str = "margin";
59const API_STOCK_COMPANY: &str = "stock_company";
60const API_MARGIN_DETAIL: &str = "margin_detail";
61const API_STK_HOLDERNUMBER: &str = "stk_holdernumber";
62const API_THS_INDEX: &str = "ths_index";
63const API_THS_MEMBER: &str = "ths_member";
64const API_THS_DAILY: &str = "ths_daily";
65const API_THS_HOT: &str = "ths_hot";
66const API_FINA_MAINBZ: &str = "fina_mainbz";
67const API_FINA_MAINBZ_VIP: &str = "fina_mainbz_vip";
68const API_FINA_INDICATOR: &str = "fina_indicator";
69const API_BALANCESHEET: &str = "balancesheet";
70const API_INCOME: &str = "income";
71const API_CASHFLOW: &str = "cashflow";
72const API_INDEX_BASIC: &str = "index_basic";
73const API_INDEX_DAILY_BASIC: &str = "index_daily_basic";
74const API_MONEYFLOW: &str = "moneyflow";
75const API_MONEYFLOW_INDUSTRY_THS: &str = "moneyflow_industry_ths";
76const API_US_BASIC: &str = "us_basic";
77const API_US_DAILY: &str = "us_daily";
78
79impl Api {
80 fn from_api_str(value: &str) -> Option<Self> {
81 let v = value.trim();
82 if v.is_empty() {
83 return None;
84 }
85
86 match v {
87 API_STOCK_BASIC => Some(Api::StockBasic),
88 API_FUND_BASIC => Some(Api::FundBasic),
89 API_FUND_DAILY => Some(Api::FundDaily),
90 API_FUND_PORTFOLIO => Some(Api::FundPortfolio),
91 API_DAILY => Some(Api::Daily),
92 API_DAILY_BASIC => Some(Api::DailyBasic),
93 API_MONEYFLOW_MKT_DC => Some(Api::MoneyflowMktDc),
94 API_WEEKLY => Some(Api::Weekly),
95 API_MONTHLY => Some(Api::Monthly),
96 API_INDEX_DAILY => Some(Api::IndexDaily),
97 API_INDEX_WEEKLY => Some(Api::IndexWeekly),
98 API_INDEX_MONTHLY => Some(Api::IndexMonthly),
99 API_TRADE_CAL => Some(Api::TradeCal),
100 API_MARGIN => Some(Api::Margin),
101 API_STOCK_COMPANY => Some(Api::StockCompany),
102 API_MARGIN_DETAIL => Some(Api::MarginDetail),
103 API_STK_HOLDERNUMBER => Some(Api::StkHoldernumber),
104 API_THS_INDEX => Some(Api::ThsIndex),
105 API_THS_MEMBER => Some(Api::ThsMember),
106 API_THS_DAILY => Some(Api::ThsDaily),
107 API_THS_HOT => Some(Api::ThsHot),
108 API_FINA_MAINBZ => Some(Api::FinaMainbz),
109 API_FINA_MAINBZ_VIP => Some(Api::FinaMainbzVip),
110 API_FINA_INDICATOR => Some(Api::FinaIndicator),
111 API_BALANCESHEET => Some(Api::Balancesheet),
112 API_INCOME => Some(Api::Income),
113 API_CASHFLOW => Some(Api::Cashflow),
114 API_INDEX_BASIC => Some(Api::IndexBasic),
115 API_INDEX_DAILY_BASIC => Some(Api::IndexDailyBasic),
116 API_MONEYFLOW => Some(Api::Moneyflow),
117 API_MONEYFLOW_INDUSTRY_THS => Some(Api::MoneyflowIndustryThs),
118 API_US_BASIC => Some(Api::UsBasic),
119 API_US_DAILY => Some(Api::UsDaily),
120 _ => None,
121 }
122 }
123
124 pub fn name(&self) -> String {
125 match self {
126 Api::StockBasic => API_STOCK_BASIC.to_string(),
127 Api::FundBasic => API_FUND_BASIC.to_string(),
128 Api::FundDaily => API_FUND_DAILY.to_string(),
129 Api::FundPortfolio => API_FUND_PORTFOLIO.to_string(),
130 Api::Daily => API_DAILY.to_string(),
131 Api::DailyBasic => API_DAILY_BASIC.to_string(),
132 Api::MoneyflowMktDc => API_MONEYFLOW_MKT_DC.to_string(),
133 Api::Weekly => API_WEEKLY.to_string(),
134 Api::Monthly => API_MONTHLY.to_string(),
135 Api::IndexDaily => API_INDEX_DAILY.to_string(),
136 Api::IndexWeekly => API_INDEX_WEEKLY.to_string(),
137 Api::IndexMonthly => API_INDEX_MONTHLY.to_string(),
138 Api::TradeCal => API_TRADE_CAL.to_string(),
139 Api::Margin => API_MARGIN.to_string(),
140 Api::StockCompany => API_STOCK_COMPANY.to_string(),
141 Api::MarginDetail => API_MARGIN_DETAIL.to_string(),
142 Api::StkHoldernumber => API_STK_HOLDERNUMBER.to_string(),
143 Api::ThsIndex => API_THS_INDEX.to_string(),
144 Api::ThsMember => API_THS_MEMBER.to_string(),
145 Api::ThsDaily => API_THS_DAILY.to_string(),
146 Api::ThsHot => API_THS_HOT.to_string(),
147 Api::FinaMainbz => API_FINA_MAINBZ.to_string(),
148 Api::FinaMainbzVip => API_FINA_MAINBZ_VIP.to_string(),
149 Api::FinaIndicator => API_FINA_INDICATOR.to_string(),
150 Api::Balancesheet => API_BALANCESHEET.to_string(),
151 Api::Income => API_INCOME.to_string(),
152 Api::Cashflow => API_CASHFLOW.to_string(),
153 Api::IndexBasic => API_INDEX_BASIC.to_string(),
154 Api::IndexDailyBasic => API_INDEX_DAILY_BASIC.to_string(),
155 Api::Moneyflow => API_MONEYFLOW.to_string(),
156 Api::MoneyflowIndustryThs => API_MONEYFLOW_INDUSTRY_THS.to_string(),
157 Api::UsBasic => API_US_BASIC.to_string(),
158 Api::UsDaily => API_US_DAILY.to_string(),
159 Api::Custom(name) => name.clone(),
160 }
161 }
162}
163
164impl<'de> Deserialize<'de> for Api {
165 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
166 where
167 D: de::Deserializer<'de>,
168 {
169 struct ApiVisitor;
170
171 impl<'de> de::Visitor<'de> for ApiVisitor {
172 type Value = Api;
173
174 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
175 formatter.write_str("a string API name")
176 }
177
178 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
179 where
180 E: de::Error,
181 {
182 if let Some(api) = Api::from_api_str(value) {
183 return Ok(api);
184 }
185 Ok(Api::Custom(value.to_string()))
186 }
187
188 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
189 where
190 E: de::Error,
191 {
192 self.visit_str(&value)
193 }
194 }
195
196 deserializer.deserialize_str(ApiVisitor)
197 }
198}
199
200pub fn serialize_api_name<S>(api: &Api, serializer: S) -> Result<S::Ok, S::Error>
202where
203 S: serde::Serializer,
204{
205 serializer.serialize_str(&api.name())
206}