Skip to main content

stock_rust/stocks/transforms/
tencent.rs

1use anyhow::{anyhow, Result};
2
3use crate::stocks::base::{COMMON_HK, COMMON_SH, COMMON_SZ, COMMON_US};
4
5use super::base::{ApiCodeTransform, CommonCodeTransform};
6
7const TENCENT_SZ: &str = "sz";
8const TENCENT_SH: &str = "sh";
9const TENCENT_HK: &str = "hk";
10const TENCENT_US: &str = "us";
11
12pub struct TencentCommonCodeTransform;
13
14impl CommonCodeTransform for TencentCommonCodeTransform {
15    fn transform(&self, code: &str) -> Result<String> {
16        if code.starts_with(COMMON_SH) {
17            return self.sh_transform(code);
18        }
19        if code.starts_with(COMMON_SZ) {
20            return self.sz_transform(code);
21        }
22        if code.starts_with(COMMON_HK) {
23            return self.hk_transform(code);
24        }
25        if code.starts_with(COMMON_US) {
26            return self.us_transform(code);
27        }
28
29        Err(anyhow!("请检查统一代码是否正确"))
30    }
31
32    fn sz_transform(&self, code: &str) -> Result<String> {
33        if !code.contains(COMMON_SZ) {
34            return Err(anyhow!("请检查统一代码是否正确"));
35        }
36        Ok(format!("{}{}", TENCENT_SZ, code.replacen(COMMON_SZ, "", 1)))
37    }
38
39    fn sh_transform(&self, code: &str) -> Result<String> {
40        if !code.contains(COMMON_SH) {
41            return Err(anyhow!("请检查统一代码是否正确"));
42        }
43        Ok(format!("{}{}", TENCENT_SH, code.replacen(COMMON_SH, "", 1)))
44    }
45
46    fn hk_transform(&self, code: &str) -> Result<String> {
47        if !code.contains(COMMON_HK) {
48            return Err(anyhow!("请检查统一代码是否正确"));
49        }
50        Ok(format!(
51            "{}{}",
52            TENCENT_HK,
53            code.replacen(COMMON_HK, "", 1).to_uppercase()
54        ))
55    }
56
57    fn us_transform(&self, code: &str) -> Result<String> {
58        if !code.contains(COMMON_US) {
59            return Err(anyhow!("请检查统一代码是否正确"));
60        }
61        Ok(format!(
62            "{}{}",
63            TENCENT_US,
64            code.replacen(COMMON_US, "", 1).to_uppercase()
65        ))
66    }
67}
68
69pub struct TencentApiCodeTransform;
70
71impl ApiCodeTransform for TencentApiCodeTransform {
72    fn transform(&self, code: &str) -> Result<String> {
73        if code.starts_with(TENCENT_SZ) {
74            return self.sz_transform(code);
75        }
76        if code.starts_with(TENCENT_SH) {
77            return self.sh_transform(code);
78        }
79        if code.starts_with(TENCENT_HK) {
80            return self.hk_transform(code);
81        }
82        if code.starts_with(TENCENT_US) {
83            return self.us_transform(code);
84        }
85
86        Err(anyhow!("请检查股票代码是否正确"))
87    }
88
89    fn sz_transform(&self, code: &str) -> Result<String> {
90        if !code.contains(TENCENT_SZ) {
91            return Err(anyhow!("请检查股票代码是否正确"));
92        }
93        Ok(format!("{}{}", COMMON_SZ, code.replacen(TENCENT_SZ, "", 1)))
94    }
95
96    fn sh_transform(&self, code: &str) -> Result<String> {
97        if !code.contains(TENCENT_SH) {
98            return Err(anyhow!("请检查股票代码是否正确"));
99        }
100        Ok(format!("{}{}", COMMON_SH, code.replacen(TENCENT_SH, "", 1)))
101    }
102
103    fn hk_transform(&self, code: &str) -> Result<String> {
104        if !code.contains(TENCENT_HK) {
105            return Err(anyhow!("请检查股票代码是否正确"));
106        }
107        Ok(format!("{}{}", COMMON_HK, code.replacen(TENCENT_HK, "", 1)))
108    }
109
110    fn us_transform(&self, code: &str) -> Result<String> {
111        if !code.contains(TENCENT_US) {
112            return Err(anyhow!("请检查股票代码是否正确"));
113        }
114        Ok(format!("{}{}", COMMON_US, code.replacen(TENCENT_US, "", 1)))
115    }
116}
117
118pub struct TencentSearchCodeTransform;
119
120impl TencentSearchCodeTransform {
121    pub fn transform(&self, market: &str, code: &str) -> String {
122        match market {
123            "sz" => format!("{}{}", COMMON_SZ, code),
124            "sh" => format!("{}{}", COMMON_SH, code),
125            "hk" => format!("{}{}", COMMON_HK, code),
126            "us" => {
127                let c = code.split('.').next().unwrap_or_default().to_uppercase();
128                format!("{}{}", COMMON_US, c)
129            }
130            _ => String::new(),
131        }
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use super::*;
138
139    #[test]
140    fn test_common_code_transform() {
141        let t = TencentCommonCodeTransform;
142        assert_eq!(t.transform("SH510500").unwrap(), "sh510500");
143        assert_eq!(t.transform("SZ399001").unwrap(), "sz399001");
144        assert_eq!(t.transform("HKhsi").unwrap(), "hkHSI");
145        assert_eq!(t.transform("USDji").unwrap(), "usDJI");
146    }
147
148    #[test]
149    fn test_api_code_transform() {
150        let t = TencentApiCodeTransform;
151        assert_eq!(t.transform("sh510500").unwrap(), "SH510500");
152        assert_eq!(t.transform("sz399001").unwrap(), "SZ399001");
153        assert_eq!(t.transform("hkHSI").unwrap(), "HKHSI");
154        assert_eq!(t.transform("usDJI").unwrap(), "USDJI");
155    }
156
157    #[test]
158    fn test_search_code_transform() {
159        let t = TencentSearchCodeTransform;
160        assert_eq!(t.transform("sh", "510500"), "SH510500");
161        assert_eq!(t.transform("sz", "399001"), "SZ399001");
162        assert_eq!(t.transform("hk", "HSI"), "HKHSI");
163        assert_eq!(t.transform("us", "dji.us"), "USDJI");
164    }
165}