tencentcloud_sms/api/send_sms/
response.rs

1use crate::api::common::ApiError;
2use serde::Deserialize;
3use std::fmt;
4
5#[derive(Debug, Deserialize)]
6#[serde(rename_all = "PascalCase")]
7pub struct SendSmsResponse {
8    pub response: ResponseBody,
9}
10
11#[derive(Debug, Deserialize)]
12#[serde(untagged)]
13pub enum ResponseBody {
14    Success(SendSmsSuccess),
15    Error(ApiError),
16}
17
18#[derive(Debug, Deserialize)]
19#[serde(rename_all = "PascalCase")]
20pub struct SendSmsSuccess {
21    pub send_status_set: Vec<SendStatus>,
22    pub request_id: String,
23}
24
25/// 短信发送状态码
26///
27/// 表示单个手机号的短信发送结果状态
28#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
29#[serde(from = "String")]
30pub enum SmsStatusCode {
31    /// 发送成功
32    Ok,
33    /// 参数错误
34    InvalidParameter,
35    /// 手机号格式错误
36    InvalidPhoneNumber,
37    /// 频率限制
38    LimitExceeded,
39    /// 余额不足
40    InsufficientBalance,
41    /// 其他错误(包含原始错误码)
42    Other(String),
43}
44
45impl From<String> for SmsStatusCode {
46    fn from(s: String) -> Self {
47        match s.as_str() {
48            "Ok" => Self::Ok,
49            code if code.starts_with("InvalidParameter") => Self::InvalidParameter,
50            code if code.contains("PhoneNumber") && code.starts_with("Invalid") => {
51                Self::InvalidPhoneNumber
52            }
53            code if code.starts_with("LimitExceeded") => Self::LimitExceeded,
54            code if code.contains("InsufficientBalance") => Self::InsufficientBalance,
55            _ => Self::Other(s),
56        }
57    }
58}
59
60impl fmt::Display for SmsStatusCode {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        write!(f, "{}", self.as_str())
63    }
64}
65
66impl SmsStatusCode {
67    /// 返回原始的错误码字符串(如果是 Other 变体)
68    pub fn as_str(&self) -> &str {
69        match self {
70            Self::Ok => "Ok",
71            Self::InvalidParameter => "InvalidParameter",
72            Self::InvalidPhoneNumber => "InvalidPhoneNumber",
73            Self::LimitExceeded => "LimitExceeded",
74            Self::InsufficientBalance => "InsufficientBalance",
75            Self::Other(s) => s.as_str(),
76        }
77    }
78
79    /// 判断是否为成功状态
80    pub fn is_success(&self) -> bool {
81        matches!(self, Self::Ok)
82    }
83
84    /// 转换为 String(用于需要 String 类型的场景)
85    pub fn to_string_owned(&self) -> String {
86        self.as_str().to_string()
87    }
88}
89
90#[derive(Debug, Clone, Deserialize)]
91#[serde(rename_all = "PascalCase")]
92pub struct SendStatus {
93    pub serial_no: String,
94    pub phone_number: String,
95    pub fee: u32,
96    pub session_context: String,
97
98    /// 发送状态码
99    pub code: SmsStatusCode,
100
101    /// 状态描述信息
102    pub message: String,
103    pub iso_code: String,
104}
105
106impl SendStatus {
107    /// 判断是否发送成功
108    pub fn is_success(&self) -> bool {
109        self.code.is_success()
110    }
111
112    /// 判断是否因频率限制失败
113    pub fn is_rate_limited(&self) -> bool {
114        self.code == SmsStatusCode::LimitExceeded
115    }
116
117    /// 判断是否因手机号无效失败
118    pub fn is_invalid_number(&self) -> bool {
119        self.code == SmsStatusCode::InvalidPhoneNumber
120    }
121}