use std::fmt; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize)] pub enum FriendlyRData { Address(Address), Service(Service), MailServer(MailServer), // Include SPF, etc ?! NameServer(NameServer), TextData(TextData), Alias(Alias), } pub enum FriendlyRType { Address, Service, MailServer, NameServer, TextData, Alias } pub struct FriendlyRecord { owner: String, friendly_type: FriendlyRType, rdata: FriendlyRData, ttl: u32, } pub struct RecordSet { friendly_type: FriendlyRType, records: Vec } pub struct RecordSetGroup { owner: String, rrsets: Vec } pub struct FriendlyRecords(Vec); #[derive(Debug, Deserialize, Serialize)] pub struct Address { pub address: String } #[derive(Debug, Deserialize, Serialize)] pub struct Service { pub service_type: String, pub port: u16, pub weight: u16, pub priority: u16, pub server: String, } pub enum ServiceType { ServiceProtocol { service_name: String, protocol: String }, Service { service_name: String }, None, } impl ServiceType { pub fn from_name(name: String) -> (Self, String) { let labels: Vec<_> = name.splitn(3, '.').collect(); let prefix: Vec<_> = labels.iter().cloned().take(2).map(|label| label.strip_prefix('_')).collect(); if prefix.is_empty() || prefix[0].is_none() { (ServiceType::None, labels[0..].join(".").to_owned()) } else if prefix.len() == 1 || prefix[1].is_none() { (ServiceType::Service { service_name: prefix[0].unwrap().into() }, labels[1..].join(".").to_owned()) } else { (ServiceType::ServiceProtocol { service_name: prefix[0].unwrap().into(), protocol: prefix[1].unwrap().into() }, labels[2].to_owned()) } } } impl fmt::Display for ServiceType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ServiceType::ServiceProtocol { service_name, protocol } => write!(f, "{}/{}", service_name, protocol), ServiceType::Service { service_name, } => write!(f, "{}", service_name), ServiceType::None => write!(f, "-"), } } } #[derive(Debug, Deserialize, Serialize)] pub struct MailServer { pub preference: u16, pub mail_exchanger: String, } #[derive(Debug, Deserialize, Serialize)] pub struct NameServer { pub target: String, } #[derive(Debug, Deserialize, Serialize)] pub struct TextData { pub text: String, } #[derive(Debug, Deserialize, Serialize)] pub struct Alias { pub target: String, }