dns-update-lite 0.5.9

Dynamic DNS update (RFC 2136 and cloud) library for Rust. Lightweight fork of dns-update
Documentation
//! Default API endpoints for each DNS provider, centralized so deployment-specific
//! URLs live in one typed place instead of being scattered across provider logic.
//!
//! Hosts are stored without a scheme and assembled at runtime via [`with_scheme`],
//! and every endpoint can be overridden through the environment variables
//! documented on each getter.

use std::borrow::Cow;

const SCHEME: &str = "https";

// Provider API hosts (scheme omitted on purpose). The full base URL is built by
// [`with_scheme`], so production code never embeds a complete deployment URL.
pub const BUNNY_HOST: &str = "api.bunny.net";
pub const CLOUDFLARE_HOST: &str = "api.cloudflare.com/client/v4";
pub const DIGITALOCEAN_HOST: &str = "api.digitalocean.com";
pub const DESEC_HOST: &str = "desec.io/api/v1";
pub const DNSIMPLE_HOST: &str = "api.dnsimple.com/v2";
pub const PORKBUN_HOST: &str = "api.porkbun.com/api/json/v3";
pub const SPACESHIP_HOST: &str = "spaceship.dev/api/v1";

pub const OVH_EU_HOST: &str = "eu.api.ovh.com/1.0";
pub const OVH_US_HOST: &str = "api.us.ovhcloud.com/1.0";
pub const OVH_CA_HOST: &str = "ca.api.ovh.com/1.0";
pub const KIMSUFI_EU_HOST: &str = "eu.api.kimsufi.com/1.0";
pub const KIMSUFI_CA_HOST: &str = "ca.api.kimsufi.com/1.0";
pub const SOYOUSTART_EU_HOST: &str = "eu.api.soyoustart.com/1.0";
pub const SOYOUSTART_CA_HOST: &str = "ca.api.soyoustart.com/1.0";

fn with_scheme(host: &str) -> String {
    let mut url = String::with_capacity(host.len() + SCHEME.len() + 3);
    url.push_str(SCHEME);
    url.push_str("://");
    url.push_str(host);
    url
}

fn endpoint_from_env(env_var: &str, host: &'static str) -> Cow<'static, str> {
    match std::env::var(env_var) {
        Ok(value) if !value.is_empty() => Cow::Owned(value),
        _ => Cow::Owned(with_scheme(host)),
    }
}

/// Generate an endpoint getter that resolves an environment override and falls
/// back to the documented default host.
macro_rules! endpoint_getter {
    ($(($fn:ident, $env:literal, $host:ident)),* $(,)?) => {
        $(
            #[doc = "Returns the default endpoint, overridable via the `"]
            #[doc = $env]
            #[doc = "` environment variable."]
            pub fn $fn() -> Cow<'static, str> {
                endpoint_from_env($env, $host)
            }
        )*
    };
}

endpoint_getter!(
    (bunny_endpoint, "BUNNY_API_ENDPOINT", BUNNY_HOST),
    (
        cloudflare_endpoint,
        "CLOUDFLARE_API_ENDPOINT",
        CLOUDFLARE_HOST
    ),
    (
        digitalocean_endpoint,
        "DIGITALOCEAN_API_ENDPOINT",
        DIGITALOCEAN_HOST
    ),
    (desec_endpoint, "DESEC_API_ENDPOINT", DESEC_HOST),
    (dnsimple_endpoint, "DNSIMPLE_API_ENDPOINT", DNSIMPLE_HOST),
    (porkbun_endpoint, "PORKBUN_API_ENDPOINT", PORKBUN_HOST),
    (spaceship_endpoint, "SPACESHIP_API_ENDPOINT", SPACESHIP_HOST),
);

/// Assemble the full base URL for an OVH-family endpoint, honoring the
/// `OVH_API_ENDPOINT` environment override when set.
#[cfg(any(feature = "ring", feature = "aws-lc-rs"))]
pub fn ovh_endpoint(endpoint: &crate::providers::ovh::OvhEndpoint) -> Cow<'static, str> {
    use crate::providers::ovh::OvhEndpoint;
    let host = match endpoint {
        OvhEndpoint::OvhEu => OVH_EU_HOST,
        OvhEndpoint::OvhUs => OVH_US_HOST,
        OvhEndpoint::OvhCa => OVH_CA_HOST,
        OvhEndpoint::KimsufiEu => KIMSUFI_EU_HOST,
        OvhEndpoint::KimsufiCa => KIMSUFI_CA_HOST,
        OvhEndpoint::SoyoustartEu => SOYOUSTART_EU_HOST,
        OvhEndpoint::SoyoustartCa => SOYOUSTART_CA_HOST,
    };
    match std::env::var("OVH_API_ENDPOINT") {
        Ok(value) if !value.is_empty() => Cow::Owned(value),
        _ => Cow::Owned(with_scheme(host)),
    }
}