use anyhow::{anyhow, Result};
use crate::stocks::base::{COMMON_HK, COMMON_SH, COMMON_SZ, COMMON_US};
use super::base::{ApiCodeTransform, CommonCodeTransform};
const TENCENT_SZ: &str = "sz";
const TENCENT_SH: &str = "sh";
const TENCENT_HK: &str = "hk";
const TENCENT_US: &str = "us";
pub struct TencentCommonCodeTransform;
impl CommonCodeTransform for TencentCommonCodeTransform {
fn transform(&self, code: &str) -> Result<String> {
if code.starts_with(COMMON_SH) {
return self.sh_transform(code);
}
if code.starts_with(COMMON_SZ) {
return self.sz_transform(code);
}
if code.starts_with(COMMON_HK) {
return self.hk_transform(code);
}
if code.starts_with(COMMON_US) {
return self.us_transform(code);
}
Err(anyhow!("请检查统一代码是否正确"))
}
fn sz_transform(&self, code: &str) -> Result<String> {
if !code.contains(COMMON_SZ) {
return Err(anyhow!("请检查统一代码是否正确"));
}
Ok(format!("{}{}", TENCENT_SZ, code.replacen(COMMON_SZ, "", 1)))
}
fn sh_transform(&self, code: &str) -> Result<String> {
if !code.contains(COMMON_SH) {
return Err(anyhow!("请检查统一代码是否正确"));
}
Ok(format!("{}{}", TENCENT_SH, code.replacen(COMMON_SH, "", 1)))
}
fn hk_transform(&self, code: &str) -> Result<String> {
if !code.contains(COMMON_HK) {
return Err(anyhow!("请检查统一代码是否正确"));
}
Ok(format!(
"{}{}",
TENCENT_HK,
code.replacen(COMMON_HK, "", 1).to_uppercase()
))
}
fn us_transform(&self, code: &str) -> Result<String> {
if !code.contains(COMMON_US) {
return Err(anyhow!("请检查统一代码是否正确"));
}
Ok(format!(
"{}{}",
TENCENT_US,
code.replacen(COMMON_US, "", 1).to_uppercase()
))
}
}
pub struct TencentApiCodeTransform;
impl ApiCodeTransform for TencentApiCodeTransform {
fn transform(&self, code: &str) -> Result<String> {
if code.starts_with(TENCENT_SZ) {
return self.sz_transform(code);
}
if code.starts_with(TENCENT_SH) {
return self.sh_transform(code);
}
if code.starts_with(TENCENT_HK) {
return self.hk_transform(code);
}
if code.starts_with(TENCENT_US) {
return self.us_transform(code);
}
Err(anyhow!("请检查股票代码是否正确"))
}
fn sz_transform(&self, code: &str) -> Result<String> {
if !code.contains(TENCENT_SZ) {
return Err(anyhow!("请检查股票代码是否正确"));
}
Ok(format!("{}{}", COMMON_SZ, code.replacen(TENCENT_SZ, "", 1)))
}
fn sh_transform(&self, code: &str) -> Result<String> {
if !code.contains(TENCENT_SH) {
return Err(anyhow!("请检查股票代码是否正确"));
}
Ok(format!("{}{}", COMMON_SH, code.replacen(TENCENT_SH, "", 1)))
}
fn hk_transform(&self, code: &str) -> Result<String> {
if !code.contains(TENCENT_HK) {
return Err(anyhow!("请检查股票代码是否正确"));
}
Ok(format!("{}{}", COMMON_HK, code.replacen(TENCENT_HK, "", 1)))
}
fn us_transform(&self, code: &str) -> Result<String> {
if !code.contains(TENCENT_US) {
return Err(anyhow!("请检查股票代码是否正确"));
}
Ok(format!("{}{}", COMMON_US, code.replacen(TENCENT_US, "", 1)))
}
}
pub struct TencentSearchCodeTransform;
impl TencentSearchCodeTransform {
pub fn transform(&self, market: &str, code: &str) -> String {
match market {
"sz" => format!("{}{}", COMMON_SZ, code),
"sh" => format!("{}{}", COMMON_SH, code),
"hk" => format!("{}{}", COMMON_HK, code),
"us" => {
let c = code.split('.').next().unwrap_or_default().to_uppercase();
format!("{}{}", COMMON_US, c)
}
_ => String::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_common_code_transform() {
let t = TencentCommonCodeTransform;
assert_eq!(t.transform("SH510500").unwrap(), "sh510500");
assert_eq!(t.transform("SZ399001").unwrap(), "sz399001");
assert_eq!(t.transform("HKhsi").unwrap(), "hkHSI");
assert_eq!(t.transform("USDji").unwrap(), "usDJI");
}
#[test]
fn test_api_code_transform() {
let t = TencentApiCodeTransform;
assert_eq!(t.transform("sh510500").unwrap(), "SH510500");
assert_eq!(t.transform("sz399001").unwrap(), "SZ399001");
assert_eq!(t.transform("hkHSI").unwrap(), "HKHSI");
assert_eq!(t.transform("usDJI").unwrap(), "USDJI");
}
#[test]
fn test_search_code_transform() {
let t = TencentSearchCodeTransform;
assert_eq!(t.transform("sh", "510500"), "SH510500");
assert_eq!(t.transform("sz", "399001"), "SZ399001");
assert_eq!(t.transform("hk", "HSI"), "HKHSI");
assert_eq!(t.transform("us", "dji.us"), "USDJI");
}
}