use crate::framework::endpoint::{serialize_query, EndpointSpec, Method, RequestBody};
use crate::framework::response::{ApiResult, ApiSuccess};
use crate::framework::{OrderDirection, SearchMatch};
use chrono::offset::Utc;
use chrono::DateTime;
use serde::{Deserialize, Serialize};
use std::net::{Ipv4Addr, Ipv6Addr};
#[derive(Debug)]
pub struct ListDnsRecords<'a> {
pub zone_identifier: &'a str,
pub params: ListDnsRecordsParams,
}
impl EndpointSpec for ListDnsRecords<'_> {
type JsonResponse = Vec<DnsRecord>;
type ResponseType = ApiSuccess<Self::JsonResponse>;
fn method(&self) -> Method {
Method::GET
}
fn path(&self) -> String {
format!("zones/{}/dns_records", self.zone_identifier)
}
#[inline]
fn query(&self) -> Option<String> {
serialize_query(&self.params)
}
}
#[derive(Debug)]
pub struct CreateDnsRecord<'a> {
pub zone_identifier: &'a str,
pub params: CreateDnsRecordParams<'a>,
}
impl EndpointSpec for CreateDnsRecord<'_> {
type JsonResponse = DnsRecord;
type ResponseType = ApiSuccess<Self::JsonResponse>;
fn method(&self) -> Method {
Method::POST
}
fn path(&self) -> String {
format!("zones/{}/dns_records", self.zone_identifier)
}
#[inline]
fn body(&self) -> Option<RequestBody> {
let body = serde_json::to_string(&self.params).unwrap();
Some(RequestBody::Json(body))
}
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Clone, Debug)]
pub struct CreateDnsRecordParams<'a> {
pub ttl: Option<u32>,
pub priority: Option<u16>,
pub proxied: Option<bool>,
pub name: &'a str,
#[serde(flatten)]
pub content: DnsContent,
}
#[derive(Debug)]
pub struct DeleteDnsRecord<'a> {
pub zone_identifier: &'a str,
pub identifier: &'a str,
}
impl EndpointSpec for DeleteDnsRecord<'_> {
type JsonResponse = DeleteDnsRecordResponse;
type ResponseType = ApiSuccess<Self::JsonResponse>;
fn method(&self) -> Method {
Method::DELETE
}
fn path(&self) -> String {
format!(
"zones/{}/dns_records/{}",
self.zone_identifier, self.identifier
)
}
}
#[derive(Debug)]
pub struct UpdateDnsRecord<'a> {
pub zone_identifier: &'a str,
pub identifier: &'a str,
pub params: UpdateDnsRecordParams<'a>,
}
impl EndpointSpec for UpdateDnsRecord<'_> {
type JsonResponse = DnsRecord;
type ResponseType = ApiSuccess<Self::JsonResponse>;
fn method(&self) -> Method {
Method::PUT
}
fn path(&self) -> String {
format!(
"zones/{}/dns_records/{}",
self.zone_identifier, self.identifier
)
}
#[inline]
fn body(&self) -> Option<RequestBody> {
let body = serde_json::to_string(&self.params).unwrap();
Some(RequestBody::Json(body))
}
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Clone, Debug)]
pub struct UpdateDnsRecordParams<'a> {
pub ttl: Option<u32>,
pub proxied: Option<bool>,
pub name: &'a str,
#[serde(flatten)]
pub content: DnsContent,
}
#[derive(Serialize, Clone, Debug)]
#[serde(rename_all = "lowercase")]
pub enum ListDnsRecordsOrder {
Type,
Name,
Content,
Ttl,
Proxied,
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Clone, Debug, Default)]
pub struct ListDnsRecordsParams {
#[serde(flatten)]
pub record_type: Option<DnsContent>,
pub name: Option<String>,
pub page: Option<u32>,
pub per_page: Option<u32>,
pub order: Option<ListDnsRecordsOrder>,
pub direction: Option<OrderDirection>,
#[serde(rename = "match")]
pub search_match: Option<SearchMatch>,
}
#[derive(Deserialize, Debug)]
pub struct Meta {}
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(tag = "type")]
#[allow(clippy::upper_case_acronyms)]
pub enum DnsContent {
A { content: Ipv4Addr },
AAAA { content: Ipv6Addr },
CNAME { content: String },
NS { content: String },
MX { content: String, priority: u16 },
TXT { content: String },
SRV { content: String },
}
#[derive(Deserialize, Debug)]
pub struct DeleteDnsRecordResponse {
pub id: String,
}
#[derive(Deserialize, Debug)]
pub struct DnsRecord {
pub meta: Meta,
pub name: String,
pub ttl: u32,
pub modified_on: DateTime<Utc>,
pub created_on: DateTime<Utc>,
pub proxiable: bool,
#[serde(flatten)]
pub content: DnsContent,
pub id: String,
pub proxied: bool,
}
impl ApiResult for DnsRecord {}
impl ApiResult for Vec<DnsRecord> {}
impl ApiResult for DeleteDnsRecordResponse {}