use regex::Regex;
use rocket::http::RawStr;
use rocket::request::FromParam;
use serde::de::{Error as DeserializeError, Unexpected, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{fmt, str};
use trust_dns::rr::Name as TrustName;
use crate::APP_CONF;
lazy_static! {
static ref ZONE_NAME_REGEX: Regex =
Regex::new(r"^(([^\\/:@&_\*]+)\.)[^\\/:@&_\*\-\.]{2,63}$").unwrap();
}
serde_string_impls!(ZoneName);
#[derive(Clone, Debug)]
pub struct ZoneName(String);
impl ZoneName {
pub fn from_str(value: &str) -> Option<ZoneName> {
if ZONE_NAME_REGEX.is_match(value) && APP_CONF.dns.zone_exists(value) {
Some(ZoneName(value.to_string().to_lowercase()))
} else {
None
}
}
pub fn from_trust(query_name: &TrustName) -> Option<ZoneName> {
let zone_string = query_name.to_string().to_lowercase();
let mut zone_len = zone_string.len();
if zone_len > 0 {
if zone_string.get((zone_len - 1)..zone_len) == Some(".") {
zone_len = zone_len - 1;
}
ZoneName::from_str(&zone_string[..zone_len])
} else {
None
}
}
pub fn to_str(&self) -> &str {
&self.0
}
}
impl<'r> FromParam<'r> for ZoneName {
type Error = &'r RawStr;
fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
ZoneName::from_str(param).ok_or(param)
}
}