1use crate::PigRabbitError;
2use serde::Serialize;
3
4use crate::types::*;
5const API_URL: &str = "https://porkbun.com/api/json/v3/";
6pub struct PRClient {
7 pub key: Keys,
8 client: reqwest::Client,
9}
10
11impl PRClient {
13 pub fn new(keys: Keys) -> Self {
14 let client = reqwest::Client::new();
15 Self { key: keys, client }
16 }
17
18 async fn send_request<T: Serialize>(
20 client: &mut reqwest::Client,
21 url: &str,
22 body: T,
23 ) -> Result<serde_json::Value, PigRabbitError> {
24 let res: serde_json::Value = client.post(url).json(&body).send().await?.json().await?;
25 Ok(res)
26 }
27
28 pub async fn ping_test(&mut self) -> Result<(), PigRabbitError> {
30 let url = format!("{API_URL}ping");
31 let res = Self::send_request(&mut self.client, &url, &self.key).await?;
32 match res["status"].as_str().unwrap() {
33 "SUCCESS" => Ok(()),
34 _ => Err(PigRabbitError::ResponseError(res)),
35 }
36 }
37
38 pub async fn add_record(
40 &mut self,
41 domain: &str,
42 record_struct: &Record,
43 ) -> Result<i64, PigRabbitError> {
44 let url = format!("{API_URL}dns/create/{domain}");
45 let body = ComplicatedBody {
46 secretapikey: &self.key.secretapikey,
47 apikey: &self.key.apikey,
48 name: &record_struct.name,
49 dtype: &record_struct.dtype,
50 content: &record_struct.content,
51 ttl: &record_struct.ttl,
52 };
53 let res = Self::send_request(&mut self.client, &url, &body).await?;
54 match res["status"].as_str().unwrap() {
55 "SUCCESS" => Ok(res["id"].as_i64().unwrap()),
56 _ => Err(PigRabbitError::ResponseError(res)),
57 }
58 }
59
60 pub async fn edit_by_domain_and_id(
66 &mut self,
67 domain: &str,
68 id: &str,
69 record_struct: &Record,
70 ) -> Result<(), PigRabbitError> {
71 let url = format!("{API_URL}dns/edit/{domain}/{id}");
72 let body = ComplicatedBody {
73 secretapikey: &self.key.secretapikey,
74 apikey: &self.key.apikey,
75 name: &record_struct.name,
76 dtype: &record_struct.dtype,
77 content: &record_struct.content,
78 ttl: &record_struct.ttl,
79 };
80 let res = Self::send_request(&mut self.client, &url, &body).await?;
81 match res["status"].as_str().unwrap() {
82 "SUCCESS" => Ok(()),
83 _ => Err(PigRabbitError::ResponseError(res)),
84 }
85 }
86
87 pub async fn edit_by_domain_subdomain_and_type(
89 &mut self,
90 domain: &str,
91 subdomain: &str,
92 record_struct: &Record,
93 ) -> Result<(), PigRabbitError> {
94 let domain_type = &record_struct.dtype;
95 let url = format!("{API_URL}dns/editByNameType/{domain}/{domain_type}/{subdomain}");
96 let body = SimpleBody {
97 secretapikey: &self.key.secretapikey,
98 apikey: &self.key.apikey,
99 content: &record_struct.content,
100 ttl: &record_struct.ttl,
101 };
102 let res = Self::send_request(&mut self.client, &url, &body).await?;
103 match res["status"].as_str().unwrap() {
104 "SUCCESS" => Ok(()),
105 _ => Err(PigRabbitError::ResponseError(res)),
106 }
107 }
108
109 pub async fn del_by_type_with_subdomain(
111 &mut self,
112 dtype: &str,
113 domain: &str,
114 subdomain: &str,
115 ) -> Result<(), PigRabbitError> {
116 let url = format!("{API_URL}dns/deleteByNameType/{domain}/{dtype}/{subdomain}");
117 let res = Self::send_request(&mut self.client, &url, &self.key).await?;
118 match res["status"].as_str().unwrap() {
119 "SUCCESS" => Ok(()),
120 _ => Err(PigRabbitError::ResponseError(res)),
121 }
122 }
123
124 pub async fn del_by_id(&mut self, domain: &str, id: &str) -> Result<(), PigRabbitError> {
126 let url = format!("{API_URL}dns/delete/{domain}/{id}");
127 let res = Self::send_request(&mut self.client, &url, &self.key).await?;
128 match res["status"].as_str().unwrap() {
129 "SUCCESS" => Ok(()),
130 _ => Err(PigRabbitError::ResponseError(res)),
131 }
132 }
133
134 pub async fn retreive_by_type_with_subdomain(
137 &mut self,
138 dtype: &str,
139 domain: &str,
140 subdomain: &str,
141 ) -> Result<Vec<RecordInfo>, PigRabbitError> {
142 let url = format!("{API_URL}dns/retrieveByNameType/{domain}/{dtype}/{subdomain}");
143 let res = Self::send_request(&mut self.client, &url, &self.key).await?;
144
145 match res["status"].as_str().unwrap() {
146 "SUCCESS" => Ok(res["records"]
147 .as_array()
148 .map(|c| {
149 c.iter()
150 .map(|m| serde_json::from_value(m.to_owned()).unwrap())
151 .collect()
152 })
153 .unwrap()),
154 _ => Err(PigRabbitError::ResponseError(res)),
155 }
156 }
157
158 pub async fn retreive_by_domain_with_id(
165 &mut self,
166 domain: &str,
167 id: &str,
168 ) -> Result<Vec<RecordInfo>, PigRabbitError> {
169 let url = format!("{API_URL}dns/retrieve/{domain}/{id}");
170 let res = Self::send_request(&mut self.client, &url, &self.key).await?;
171
172 match res["status"].as_str().unwrap() {
173 "SUCCESS" => Ok(res["records"]
174 .as_array()
175 .map(|c| {
176 c.iter()
177 .map(|m| serde_json::from_value(m.to_owned()).unwrap())
178 .collect()
179 })
180 .unwrap()),
181 _ => Err(PigRabbitError::ResponseError(res)),
182 }
183 }
184
185 pub async fn retreive_ssl_by_domain(
187 &mut self,
188 domain: &str,
189 ) -> Result<Certificate, PigRabbitError> {
190 let url = format!("{API_URL}ssl/retrieve/{domain}");
191 let res = Self::send_request(&mut self.client, &url, &self.key).await?;
192
193 match res["status"].as_str().unwrap() {
194 "SUCCESS" => Ok(serde_json::from_value(res).unwrap()),
195 _ => Err(PigRabbitError::ResponseError(res)),
196 }
197 }
198}