dnspod_lib/
data_types.rs

1//! 参数类型
2//! <https://cloud.tencent.com/document/api/1427/78480>
3
4#![allow(unused)]
5
6use std::str::FromStr;
7
8use chrono::DateTime;
9use chrono::NaiveDate;
10use chrono::TimeZone;
11use chrono::Utc;
12use literal_enum::LiteralEnum;
13use serde::Deserialize;
14use serde::Serialize;
15
16pub type String = std::string::String;
17pub type Date = std::string::String; // DnsPodDate
18pub type Timestamp = std::string::String; // DnsPodTimestamp
19pub type Integer = u64;
20pub type Boolean = bool;
21pub type Float = f32;
22pub type Double = f32;
23pub type Binary = Vec<u8>;
24
25#[derive(Debug, Default, Clone, LiteralEnum, Serialize, Deserialize)]
26#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
27pub enum ContentType {
28    #[default]
29    #[lit = "application/json; charset=utf-8"]
30    #[serde(rename = "application/json; charset=utf-8")]
31    #[cfg_attr(feature = "clap", clap(name = "application/json; charset=utf-8"))]
32    JSON,
33}
34
35#[derive(Debug, Default, Clone, LiteralEnum, Serialize, Deserialize)]
36#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
37pub enum Language {
38    #[default]
39    #[lit = "en-US"]
40    #[serde(rename = "en-US")]
41    #[cfg_attr(feature = "clap", clap(name = "en-US"))]
42    EnUS,
43    #[lit = "zh-CN"]
44    #[serde(rename = "zh-CN")]
45    #[cfg_attr(feature = "clap", clap(name = "zh-CN"))]
46    ZhCN,
47}
48
49#[derive(Debug, Default, Clone, LiteralEnum, Serialize, Deserialize)]
50#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
51pub enum Version {
52    #[default]
53    #[lit = "2021-03-23"]
54    #[serde(rename = "2021-03-23")]
55    #[cfg_attr(feature = "clap", clap(name = "2021-03-23"))]
56    Version2021_03_23,
57}
58
59#[derive(Debug, Clone, LiteralEnum, Serialize, Deserialize)]
60#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
61pub enum Region {}
62
63#[derive(Debug, Default, Clone, LiteralEnum, Serialize, Deserialize)]
64#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
65pub enum RecordType {
66    /// A 记录是最常用类型,将域名指向一个 IPv4 地址,如 8.8.8.8
67    #[default]
68    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
69    A,
70    /// 将域名指向另一个域名地址,与其保持相同解析,如 <https://www.dnspod.cn>
71    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
72    CNAME,
73    /// 用于邮件服务器,相关参数一般由邮件注册商提供
74    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
75    MX,
76    /// 可填写附加文本信息,常用于域名验证
77    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
78    TXT,
79    /// 将域名指向一个 IPv6 地址,如 ff06:0:0:0:0:0:0:c3
80    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
81    AAAA,
82    /// 域名服务器记录,可将指定域名交由其他 DNS 服务商解析管理
83    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
84    NS,
85    /// 用于指定域名的证书颁发机构(CA),减少证书颁发风险
86    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
87    CAA,
88    /// 用于标识某台服务器使用了某个服务,常见于微软系统的目录管理。格式为「服务名字.协议类型」,如 _sip._tcp
89    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
90    SRV,
91    /// HTTPS 服务绑定记录,有助于提升 HTTPS 安全性及性能
92    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
93    HTTPS,
94    /// 新型服务绑定记录类型,允许服务指向多个客户端,并关联自定义参数值
95    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
96    SVCB,
97    /// 用于指定发送邮件的服务器,是一种高效的反垃圾邮件解决方案
98    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
99    SPF,
100    /// 将一个域名重定向至某个具体网页,且显示实际 URL 。仅支持 301 重定向,该记录要求双方域名均已完成备案。
101    #[cfg_attr(feature = "clap", clap(name = "显性URL"))]
102    显性URL,
103    /// 将一个域名重定向至某个具体网页,但隐藏实际 URL 。仅支持 301 重定向,该记录要求双方域名均已完成备案。
104    #[cfg_attr(feature = "clap", clap(name = "隐性URL"))]
105    隐性URL,
106}
107
108#[derive(Debug, Clone, Default, LiteralEnum, Serialize, Deserialize)]
109#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
110pub enum RecordLine {
111    #[default]
112    #[cfg_attr(feature = "clap", clap(name = "默认"))]
113    默认,
114}
115
116/// 域名分组类型 ALL,默认为ALL  
117/// 可取值为: MINE,SHARE,ISMARK,PAUSE,VIP,RECENT,SHARE_OUT,FREE
118#[allow(non_camel_case_types)]
119#[derive(Debug, Clone, Default, LiteralEnum, Serialize, Deserialize)]
120#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
121pub enum DomainType {
122    #[default]
123    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
124    ALL,
125    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
126    MINE,
127    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
128    SHARE,
129    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
130    ISMARK,
131    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
132    PAUSE,
133    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
134    VIP,
135    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
136    RECENT,
137    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
138    SHARE_OUT,
139    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
140    FREE,
141}
142
143#[allow(non_camel_case_types)]
144#[derive(Debug, Clone, Default, LiteralEnum, Serialize, Deserialize)]
145#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
146pub enum DomainGrade {
147    /// 免费套餐
148    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
149    D_FREE,
150    /// 个人豪华
151    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
152    D_PLUS,
153    /// 企业1
154    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
155    D_EXTRA,
156    /// 企业2
157    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
158    D_EXPERT,
159    /// 企业3
160    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
161    D_ULTRA,
162    /// 免费
163    #[default]
164    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
165    DP_FREE,
166    /// 个人专业版
167    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
168    DP_PLUS,
169    /// 企业创业版
170    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
171    DP_EXTRA,
172    /// 企业标准版
173    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
174    DP_EXPERT,
175    /// 企业旗舰版
176    #[cfg_attr(feature = "clap", clap(rename_all = "UPPER"))]
177    DP_ULTRA,
178}
179
180
181
182/// 注意: 服务器有时会返回 "0000-00-00", 会导致 date 解析出错
183/// 所以直接用 String 会有更好的兼容性
184#[derive(Debug, Clone)]
185pub struct DnsPodDate {
186    pub date: Option<NaiveDate>,
187}
188
189/// <https://serde.rs/custom-date-format.html>
190impl Serialize for DnsPodDate {
191    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
192    where
193        S: serde::Serializer,
194    {
195        if let Some(ref date) = self.date {
196            let s = date.to_string();
197            serializer.serialize_str(&s)
198        } else {
199            serializer.serialize_str("0000-00-00")
200        }
201    }
202}
203
204impl<'de> Deserialize<'de> for DnsPodDate {
205    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
206    where
207        D: serde::Deserializer<'de>,
208    {
209        let s = String::deserialize(deserializer)?;
210        match NaiveDate::from_str(&s) {
211            Ok(date) => Ok(Self { date: Some(date) }),
212            Err(_) => Ok(Self { date: None }),
213        }
214    }
215}
216
217
218#[test]
219#[should_panic]
220fn should_panic() {
221    // https://serde.rs/custom-date-format.html
222    const FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";
223    let s = "\"0000-00-00 00:00:00\"";
224    let dt = Utc.datetime_from_str(s, FORMAT).unwrap();
225}
226
227#[test]
228fn test() {
229    let s = "\"0000-01-01 00:00:00\"";
230    let t: Timestamp = serde_json::from_str(s).unwrap();
231    let s = serde_json::to_string_pretty(&t).unwrap();
232
233    println!("t: {:?}", t);
234    println!("s: {:?}", s);
235
236    let s = "\"2023-09-03\"";
237    let d: Date = serde_json::from_str(s).unwrap();
238    let s = serde_json::to_string_pretty(&d).unwrap();
239    println!("d: {:?}", d);
240    println!("s: {:?}", s);
241}