use self::types::{
DomainCheckResponse, DomainInfo, DomainListRequest, DomainListResponse, GlueRecordIps, GlueRecordListResponse,
GlueRecordRequest, NameserverListResponse, NameserverUpdateRequest, UrlForwardCreateRequest, UrlForwardListResponse,
UrlForwardRecord,
};
use super::{
client::Porkbun,
endpoints,
types::{Auth, StatusResponse},
};
use crate::Result;
use std::net::IpAddr;
pub mod types;
pub struct Domain<'a> {
client: &'a Porkbun,
domain: &'a str,
}
impl<'a> Domain<'a> {
pub(super) fn new(client: &'a Porkbun, domain: &'a str) -> Self {
Self { client, domain }
}
pub async fn update_nameservers(&self, nameservers: &[&str]) -> Result<StatusResponse> {
let path = format!("{}{}", endpoints::DOMAIN_UPDATE_NS, self.domain);
let body = NameserverUpdateRequest {
auth: self.client.auth.clone(),
ns: nameservers,
};
self.client.post(&path, &body).await
}
pub async fn get_nameservers(&self) -> Result<NameserverListResponse> {
let path = format!("{}{}", endpoints::DOMAIN_GET_NS, self.domain);
self.client.post(&path, &self.client.auth).await
}
pub async fn list_all(&self, include_labels: bool) -> Result<Vec<DomainInfo>> {
let mut all_domains = Vec::new();
let mut start = 0;
loop {
let body = DomainListRequest {
auth: self.client.auth.clone(),
start: Some(start),
include_labels: if include_labels { Some("yes".to_string()) } else { None },
};
let response: DomainListResponse = self.client.post(endpoints::DOMAIN_LIST_ALL, &body).await?;
if response.domains.is_empty() {
break;
}
start += response.domains.len() as u64;
all_domains.extend(response.domains);
}
Ok(all_domains)
}
pub async fn add_url_forward(&self, options: &UrlForwardRecord) -> Result<StatusResponse> {
let path = format!("{}{}", endpoints::DOMAIN_ADD_URL_FORWARD, self.domain);
let body = UrlForwardCreateRequest {
auth: self.client.auth.clone(),
subdomain: if options.subdomain.is_empty() {
None
} else {
Some(&options.subdomain)
},
location: &options.location,
r#type: &options.r#type,
include_path: &options.include_path,
wildcard: &options.wildcard,
};
self.client.post(&path, &body).await
}
pub async fn get_url_forwarding(&self) -> Result<Vec<UrlForwardRecord>> {
let path = format!("{}{}", endpoints::DOMAIN_GET_URL_FORWARDING, self.domain);
let response: UrlForwardListResponse = self.client.post(&path, &self.client.auth).await?;
Ok(response.forwards)
}
pub async fn delete_url_forward(&self, record_id: u64) -> Result<StatusResponse> {
let path = format!("{}{}/{}", endpoints::DOMAIN_DELETE_URL_FORWARD, self.domain, record_id);
self.client.post(&path, &self.client.auth).await
}
pub async fn check(&self) -> Result<DomainCheckResponse> {
let path = format!("{}{}", endpoints::DOMAIN_CHECK, self.domain);
self.client.post(&path, &self.client.auth).await
}
pub async fn create_glue_record(&self, subdomain: &str, ips: &[IpAddr]) -> Result<StatusResponse> {
let path = format!("{}{}/{}", endpoints::DOMAIN_CREATE_GLUE, self.domain, subdomain);
let body = GlueRecordRequest {
auth: self.client.auth.clone(),
ips: ips.to_vec(),
};
self.client.post(&path, &body).await
}
pub async fn update_glue_record(&self, subdomain: &str, ips: &[IpAddr]) -> Result<StatusResponse> {
let path = format!("{}{}/{}", endpoints::DOMAIN_UPDATE_GLUE, self.domain, subdomain);
let body = GlueRecordRequest {
auth: self.client.auth.clone(),
ips: ips.to_vec(),
};
self.client.post(&path, &body).await
}
pub async fn delete_glue_record(&self, subdomain: &str) -> Result<StatusResponse> {
let path = format!("{}{}/{}", endpoints::DOMAIN_DELETE_GLUE, self.domain, subdomain);
self.client.post(&path, &self.client.auth).await
}
pub async fn get_glue_records(&self) -> Result<Vec<(String, GlueRecordIps)>> {
let path = format!("{}{}", endpoints::DOMAIN_GET_GLUE, self.domain);
let response: GlueRecordListResponse = self.client.post(&path, &self.client.auth).await?;
Ok(response.hosts)
}
}