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 updating an existing DNS record.
///
/// Created by [`ScalewayApi::update_dns_record`](crate::ScalewayApi::update_dns_record).
/// Call [`run`](Self::run) or [`run_async`](Self::run_async) to execute.
pub struct ScalewayUpdateDnsRecordBuilder {
    api: ScalewayApi,
    dns_zone: String,
    record_id: 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 SetChange {
    set: SetChangeBody,
}

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

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

impl ScalewayUpdateDnsRecordBuilder {
    pub fn new(
        api: ScalewayApi,
        dns_zone: &str,
        record_id: &str,
        name: &str,
        record_type: DnsRecordType,
        data: &str,
    ) -> Self {
        ScalewayUpdateDnsRecordBuilder {
            api,
            dns_zone: dns_zone.to_string(),
            record_id: record_id.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.
    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.
    pub fn comment(mut self, comment: &str) -> Self {
        self.record.comment = Some(comment.to_string());
        self
    }

    fn build_request(&self) -> SetDnsRecordsRequest {
        SetDnsRecordsRequest {
            changes: vec![SetChange {
                set: SetChangeBody {
                    id: self.record_id.clone(),
                    records: vec![self.record.clone()],
                },
            }],
        }
    }

    /// Executes the update and returns the updated list of records in the zone (blocking).
    ///
    /// See [`run_async`](Self::run_async) for the async version.
    #[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 update and returns the updated list of records in the zone.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # #[tokio::main]
    /// # async fn main() -> Result<(), scaleway_rs::ScalewayError> {
    /// let api = scaleway_rs::ScalewayApi::new("my-secret-token");
    /// let records = api
    ///     .update_dns_record("example.com", "record-uuid", "www", scaleway_rs::DnsRecordType::A, "1.2.3.4")
    ///     .ttl(3600)
    ///     .run_async()
    ///     .await?;
    /// println!("Zone now has {} records", records.len());
    /// # Ok(())
    /// # }
    /// ```
    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)
    }
}