use std::error::Error; use reqwest::Client; use serde::Deserialize; use serde_json::json; use crate::config::Auth; pub struct Record { pub id: String, pub record_type: String, pub domain: String, pub subdomain: String, pub value: String, pub ttl: String, } const API: &str = "https://api.porkbun.com/api/json/v3"; #[derive(Deserialize)] struct RecordsResponse { records: Vec, } #[derive(Deserialize)] struct RecordResponse { id: String, #[serde(rename = "type")] record_type: String, name: String, content: String, ttl: String, } impl RecordResponse { fn into_model(self, domain: &str) -> Record { let subdomain = self.name .strip_suffix(domain).unwrap() .strip_suffix(".").unwrap_or(""); Record { id: self.id, record_type: self.record_type, domain: domain.to_string(), subdomain: subdomain.to_string(), value: self.content, ttl: self.ttl, } } } pub async fn get_records( client: &Client, auth: &Auth, domain: &str, ) -> Result, Box> { let body = json!({ "apikey": auth.key, "secretapikey": auth.secret_key, }); let request = client.post(format!("{API}/dns/retrieve/{domain}")) .json(&body) .send().await?; let response = request.json::().await?; let records = response.records .into_iter() .map(|it| it.into_model(domain)) .collect(); Ok(records) } pub async fn update_record( client: &Client, auth: &Auth, record: &Record, value: &str, ) -> Result<(), Box> { let body = json!({ "apikey": auth.key, "secretapikey": auth.secret_key, "type": record.record_type, "name": record.subdomain, "content": value, "ttl": record.ttl, }); client.post(format!("{API}/dns/edit/{domain}/{id}", domain = record.domain, id = record.id)) .json(&body) .send().await?; Ok(()) }