195 lines
4.2 KiB
Rust
195 lines
4.2 KiB
Rust
use std::{fmt, ops::Deref};
|
|
use domain::base::scan::Symbol;
|
|
use serde::{Serialize, Deserialize, Serializer};
|
|
|
|
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
pub struct Label {
|
|
label: String
|
|
}
|
|
|
|
impl Label {
|
|
pub fn new(label: String) -> Self {
|
|
Label {
|
|
label,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for Label {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
serializer.serialize_str(&self.to_string())
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Label {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", self.label)
|
|
}
|
|
}
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
|
|
pub struct Name {
|
|
name: String
|
|
}
|
|
|
|
impl Name {
|
|
pub fn new(name: String) -> Self {
|
|
Name {
|
|
name,
|
|
}
|
|
}
|
|
|
|
pub fn ends_with(&self, other: &Name) -> bool {
|
|
self.name == other.name || self.name.ends_with(&(String::from(".") + &other.name))
|
|
}
|
|
}
|
|
|
|
impl Serialize for Name {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
serializer.serialize_str(&self.to_string())
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Name {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", self.name)
|
|
}
|
|
}
|
|
|
|
impl Ord for Name {
|
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
let mut labels = self.name.split('.').rev();
|
|
let mut other_labels = other.name.split('.').rev();
|
|
|
|
loop {
|
|
match (labels.next(), other_labels.next()) {
|
|
(Some(label), Some(other_label)) => match label.cmp(other_label) {
|
|
std::cmp::Ordering::Equal => (),
|
|
res => return res,
|
|
},
|
|
(None, Some(_)) => return std::cmp::Ordering::Less,
|
|
(Some(_), None) => return std::cmp::Ordering::Greater,
|
|
(None, None) => return std::cmp::Ordering::Equal,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PartialOrd for Name {
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
Some(self.cmp(other))
|
|
}
|
|
}
|
|
|
|
#[derive(Eq, PartialEq)]
|
|
pub enum Rtype {
|
|
A,
|
|
Aaaa,
|
|
Cname,
|
|
Mx,
|
|
Ns,
|
|
Ptr,
|
|
Soa,
|
|
Srv,
|
|
Txt
|
|
}
|
|
|
|
impl Rtype {
|
|
pub fn value(&self) -> u16 {
|
|
match self {
|
|
Rtype::A => 1,
|
|
Rtype::Aaaa => 28,
|
|
Rtype::Cname => 5,
|
|
Rtype::Mx => 15,
|
|
Rtype::Ns => 2,
|
|
Rtype::Ptr => 12,
|
|
Rtype::Soa => 6,
|
|
Rtype::Srv => 33,
|
|
Rtype::Txt => 16,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Ord for Rtype {
|
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
self.value().cmp(&other.value())
|
|
}
|
|
}
|
|
|
|
impl PartialOrd for Rtype {
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
Some(self.cmp(other))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
pub struct Text {
|
|
pub data: Vec<u8>
|
|
}
|
|
|
|
impl Text {
|
|
pub fn new(data: Vec<u8>) -> Self {
|
|
Text {
|
|
data,
|
|
}
|
|
}
|
|
|
|
pub fn bytes(self) -> Vec<u8> {
|
|
self.data
|
|
}
|
|
|
|
pub fn add_prefix_if_not_present<B: AsRef<[u8]>>(&self, prefix: B) -> Text {
|
|
let mut data = Vec::new();
|
|
data.extend_from_slice(prefix.as_ref());
|
|
|
|
if !self.data.starts_with(prefix.as_ref()) {
|
|
data.extend_from_slice(&self.data);
|
|
}
|
|
|
|
Text::new(data)
|
|
}
|
|
|
|
pub fn strip_prefix<B: AsRef<[u8]>>(&self, prefix: B) -> Text{
|
|
self.data.strip_prefix(prefix.as_ref())
|
|
.map(|data| Text::new(data.into()))
|
|
.unwrap_or_else(|| self.clone())
|
|
}
|
|
}
|
|
|
|
impl Deref for Text {
|
|
type Target = Vec<u8>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.data
|
|
}
|
|
}
|
|
|
|
impl Serialize for Text {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
serializer.serialize_str(&self.to_string())
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Text {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
for c in &self.data {
|
|
// Escapes '\' and non printable chars
|
|
let c = Symbol::display_from_octet(*c);
|
|
write!(f, "{}", c)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|