edge-schema 0.1.0

Shared schema types for Wasmer Edge.
Documentation
use std::net::{Ipv4Addr, Ipv6Addr};

use serde::{Deserialize, Serialize};
use time::OffsetDateTime;

use super::EntityDescriptorConst;

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct DnsRecordSpecV1 {
    pub external_id: Option<String>,
    /// Root domain as text.
    pub root_domain: String,
    /// Root domain as entity reference.
    pub root_domain_external_id: Option<String>,
    pub data: DnsRecordData,
}

impl DnsRecordSpecV1 {
    pub fn kind(&self) -> DnsRecordKind {
        self.data.kind_name()
    }

    pub fn full_domain(&self) -> String {
        let name = self.data.common().name.trim().trim_end_matches('.');

        if name.is_empty() || name == "@" {
            self.root_domain.clone()
        } else {
            format!("{}.{}", name, self.root_domain)
        }
    }
}

impl EntityDescriptorConst for DnsRecordSpecV1 {
    const NAMESPACE: &'static str = "wasmer.io";
    const NAME: &'static str = "DnsRecord";
    const VERSION: &'static str = "v1";
    const KIND: &'static str = "wasmer.io/DnsRecord.v1";

    type Spec = Self;
    type State = ();
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Debug, schemars::JsonSchema)]
pub enum DnsRecordKind {
    A,
    Aaaa,
    CName,
    Txt,
    Mx,
    Ns,
    Caa,
    DName,
    Ptr,
    Soa,
}

impl DnsRecordKind {
    pub fn as_str(&self) -> &str {
        match self {
            Self::A => "A",
            Self::Aaaa => "AAAA",
            Self::CName => "CNAME",
            Self::Txt => "TXT",
            Self::Mx => "MX",
            Self::Ns => "NS",
            Self::Caa => "CAA",
            Self::DName => "DNAME",
            Self::Ptr => "PTR",
            Self::Soa => "SOA",
        }
    }
}

impl std::fmt::Display for DnsRecordKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub enum DnsRecordData {
    #[serde(rename = "a")]
    A(ARecord),
    #[serde(rename = "aaaa")]
    Aaaa(AaaaRecord),
    #[serde(rename = "cname")]
    CName(CNameRecord),
    #[serde(rename = "txt")]
    Txt(TxtRecord),
    #[serde(rename = "mx")]
    Mx(MxRecord),
    #[serde(rename = "ns")]
    Ns(NsRecord),
    #[serde(rename = "caa")]
    Caa(CaaRecord),
    #[serde(rename = "dname")]
    DName(DNameRecord),
    #[serde(rename = "ptr")]
    Ptr(PtrRecord),
    #[serde(rename = "soa")]
    Soa(SoaRecord),
}

impl DnsRecordData {
    pub fn common(&self) -> &DnsRecordCommon {
        match self {
            DnsRecordData::A(x) => &x.common,
            DnsRecordData::Aaaa(x) => &x.common,
            DnsRecordData::CName(x) => &x.common,
            DnsRecordData::Txt(x) => &x.common,
            DnsRecordData::Mx(x) => &x.common,
            DnsRecordData::Ns(x) => &x.common,
            DnsRecordData::Caa(x) => &x.common,
            DnsRecordData::DName(x) => &x.common,
            DnsRecordData::Ptr(x) => &x.common,
            DnsRecordData::Soa(x) => &x.common,
        }
    }

    pub fn kind_name(&self) -> DnsRecordKind {
        match self {
            DnsRecordData::A(_) => DnsRecordKind::A,
            DnsRecordData::Aaaa(_) => DnsRecordKind::Aaaa,
            DnsRecordData::CName(_) => DnsRecordKind::CName,
            DnsRecordData::Txt(_) => DnsRecordKind::Txt,
            DnsRecordData::Mx(_) => DnsRecordKind::Mx,
            DnsRecordData::Ns(_) => DnsRecordKind::Ns,
            DnsRecordData::Caa(_) => DnsRecordKind::Caa,
            DnsRecordData::DName(_) => DnsRecordKind::DName,
            DnsRecordData::Ptr(_) => DnsRecordKind::Ptr,
            DnsRecordData::Soa(_) => DnsRecordKind::Soa,
        }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct ARecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    #[schemars(with = "String")]
    pub address: Ipv4Addr,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct AaaaRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub address: Ipv6Addr,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct CNameRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub cname: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct TxtRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub data: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct MxRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub mx: String,
    pub preference: u16,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct NsRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub nameserver: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct CaaRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub value: String,
    pub flags: i32,
    pub tag: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct DNameRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub dname: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct PtrRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub ptr: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct SoaRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,
    pub mname: String,
    pub rname: String,
    pub serial: i64,
    pub refresh: i64,
    pub retry: i64,
    pub expire: i64,
    pub minimum: i64,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct SrvRecord {
    #[serde(flatten)]
    pub common: DnsRecordCommon,

    pub service: String,
    pub protocol: String,
    pub priority: i32,
    pub weight: i32,
    pub port: i32,
    pub target: String,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct DnsRecordCommon {
    pub name: String,
    pub ttl: Seconds,
    #[serde(
        default,
        with = "time::serde::timestamp::option",
        skip_serializing_if = "Option::is_none"
    )]
    #[schemars(with = "Option<u64>")]
    pub created_at: Option<OffsetDateTime>,
    #[serde(
        default,
        with = "time::serde::timestamp::option",
        skip_serializing_if = "Option::is_none"
    )]
    #[schemars(with = "Option<u64>")]
    pub updated_at: Option<OffsetDateTime>,
    #[serde(
        default,
        with = "time::serde::timestamp::option",
        skip_serializing_if = "Option::is_none"
    )]
    #[schemars(with = "Option<u64>")]
    pub deleted_at: Option<OffsetDateTime>,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, schemars::JsonSchema)]
pub struct Seconds(pub u32);