scaleway-rs 0.2.8

A pure Rust scaleway API binding.
Documentation
use crate::data::dns_record::{DnsRecordType, ScalewayDnsRecord, ScalewayDnsRecordsRoot};
use crate::{ScalewayApi, ScalewayError};
use serde::Serialize;

/// Builder for adding a DNS record to a zone.
///
/// Created by [`ScalewayApi::add_dns_record`](crate::ScalewayApi::add_dns_record).
/// Set optional fields then call [`run`](Self::run) or [`run_async`](Self::run_async).
pub struct ScalewayAddDnsRecordBuilder {
    api: ScalewayApi,
    dns_zone: String,
    record: DnsRecordInput,
}

#[derive(Serialize, Clone)]
struct DnsRecordInput {
    data: String,
    name: String,
    #[serde(rename = "type")]
    record_type: DnsRecordType,
    #[serde(skip_serializing_if = "Option::is_none")]
    ttl: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    priority: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    comment: Option<String>,
}

#[derive(Serialize)]
struct AddChange {
    add: AddChangeRecords,
}

#[derive(Serialize)]
struct AddChangeRecords {
    records: Vec<DnsRecordInput>,
}

#[derive(Serialize)]
struct AddDnsRecordsRequest {
    changes: Vec<AddChange>,
}

impl ScalewayAddDnsRecordBuilder {
    pub fn new(api: ScalewayApi, dns_zone: &str, name: &str, record_type: DnsRecordType, data: &str) -> Self {
        ScalewayAddDnsRecordBuilder {
            api,
            dns_zone: dns_zone.to_string(),
            record: DnsRecordInput {
                data: data.to_string(),
                name: name.to_string(),
                record_type,
                ttl: None,
                priority: None,
                comment: None,
            },
        }
    }

    /// Sets the TTL (time-to-live) for this record in seconds. Defaults to the zone's TTL.
    pub fn ttl(mut self, ttl: u32) -> Self {
        self.record.ttl = Some(ttl);
        self
    }

    /// Sets the priority for MX or SRV records (lower number = higher priority).
    pub fn priority(mut self, priority: u32) -> Self {
        self.record.priority = Some(priority);
        self
    }

    /// Attaches a human-readable comment to this record (visible in the console).
    pub fn comment(mut self, comment: &str) -> Self {
        self.record.comment = Some(comment.to_string());
        self
    }

    fn build_request(&self) -> AddDnsRecordsRequest {
        AddDnsRecordsRequest {
            changes: vec![AddChange {
                add: AddChangeRecords {
                    records: vec![self.record.clone()],
                },
            }],
        }
    }

    /// Executes the request and returns the updated list of records in the zone (blocking).
    #[cfg(feature = "blocking")]
    pub fn run(self) -> Result<Vec<ScalewayDnsRecord>, ScalewayError> {
        let url = format!(
            "https://api.scaleway.com/domain/v2beta1/dns-zones/{dns_zone}/records",
            dns_zone = self.dns_zone
        );
        let req = self.build_request();
        Ok(self.api.post(&url, req)?.json::<ScalewayDnsRecordsRoot>()?.records)
    }

    /// Executes the request and returns the updated list of records in the zone.
    pub async fn run_async(self) -> Result<Vec<ScalewayDnsRecord>, ScalewayError> {
        let url = format!(
            "https://api.scaleway.com/domain/v2beta1/dns-zones/{dns_zone}/records",
            dns_zone = self.dns_zone
        );
        let req = self.build_request();
        Ok(self
            .api
            .post_async(&url, req)
            .await?
            .json::<ScalewayDnsRecordsRoot>()
            .await?
            .records)
    }
}