rust-dnsbox/lib/dnsbox-base/src/common_types/name/compressed_name.rs

127 lines
2.8 KiB
Rust

use crate::errors::*;
use crate::ser::packet::{DnsPacketData, DnsPacketWriteContext};
use crate::ser::text::{next_field, parse_with, DnsTextContext, DnsTextData, DnsTextFormatter};
use bytes::Bytes;
use std::fmt;
use std::io::Cursor;
use std::ops::{Deref, DerefMut};
use std::str::FromStr;
use super::{DnsLabelRef, DnsName, DnsNameIterator};
/// Similar to `DnsName`, but allows using compressed labels in the
/// serialized form
#[derive(Clone)]
pub struct DnsCompressedName(pub DnsName);
impl DnsCompressedName {
/// Create new name representing the DNS root (".")
pub fn new_root() -> Self {
DnsCompressedName(DnsName::new_root())
}
/// Parse text representation of a domain name
pub fn parse(context: &DnsTextContext, value: &str) -> Result<Self> {
Ok(DnsCompressedName(DnsName::parse(context, value)?))
}
}
impl Deref for DnsCompressedName {
type Target = DnsName;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for DnsCompressedName {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AsRef<DnsName> for DnsCompressedName {
fn as_ref(&self) -> &DnsName {
&self.0
}
}
impl AsMut<DnsName> for DnsCompressedName {
fn as_mut(&mut self) -> &mut DnsName {
&mut self.0
}
}
impl<'a> IntoIterator for &'a DnsCompressedName {
type Item = DnsLabelRef<'a>;
type IntoIter = DnsNameIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.labels()
}
}
impl PartialEq<DnsName> for DnsCompressedName {
fn eq(&self, rhs: &DnsName) -> bool {
let this: &DnsName = self;
this == rhs
}
}
impl<T> PartialEq<T> for DnsCompressedName
where
T: AsRef<DnsName>,
{
fn eq(&self, rhs: &T) -> bool {
let this: &DnsName = self.as_ref();
this == rhs
}
}
impl Eq for DnsCompressedName {}
impl fmt::Debug for DnsCompressedName {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(w)
}
}
impl fmt::Display for DnsCompressedName {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(w)
}
}
impl FromStr for DnsCompressedName {
type Err = ::failure::Error;
fn from_str(s: &str) -> Result<Self> {
parse_with(s, |data| {
DnsCompressedName::dns_parse(&DnsTextContext::new(), data)
})
}
}
impl DnsTextData for DnsCompressedName {
fn dns_parse(context: &DnsTextContext, data: &mut &str) -> Result<Self> {
let field = next_field(data)?;
DnsCompressedName::parse(context, field)
}
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
self.0.dns_format(f)
}
}
impl DnsPacketData for DnsCompressedName {
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
Ok(DnsCompressedName(
super::name_packet_parser::deserialize_name(data, true)?,
))
}
fn serialize(&self, context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
context.write_compressed_name(packet, self)
}
}