use std::{fmt, ops};
use std::net::Ipv4Addr;
use std::str::FromStr;
use bytes::{BufMut, Bytes, BytesMut};
use ::iana::Rtype;
use ::bits::charstr::CharStr;
use ::bits::compose::{Compose, Compress, Compressor};
use ::bits::name::ParsedDname;
use ::bits::parse::{ParseAll, ParseAllError, ParseOpenError, Parse,
Parser, ShortBuf};
use ::bits::rdata::RtypeRecordData;
use ::bits::serial::Serial;
use ::master::scan::{CharSource, ScanError, Scan, Scanner};
macro_rules! dname_type {
($target:ident, $rtype:ident, $field:ident) => {
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct $target<N> {
$field: N
}
impl<N> $target<N> {
pub fn new($field: N) -> Self {
$target { $field: $field }
}
pub fn $field(&self) -> &N {
&self.$field
}
}
impl<N> From<N> for $target<N> {
fn from(name: N) -> Self {
Self::new(name)
}
}
impl<N: FromStr> FromStr for $target<N> {
type Err = N::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
N::from_str(s).map(Self::new)
}
}
impl Parse for $target<ParsedDname> {
type Err = <ParsedDname as Parse>::Err;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
ParsedDname::parse(parser).map(Self::new)
}
fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
ParsedDname::skip(parser).map_err(Into::into)
}
}
impl ParseAll for $target<ParsedDname> {
type Err = <ParsedDname as ParseAll>::Err;
fn parse_all(parser: &mut Parser, len: usize)
-> Result<Self, Self::Err> {
ParsedDname::parse_all(parser, len).map(Self::new)
}
}
impl<N: Compose> Compose for $target<N> {
fn compose_len(&self) -> usize {
self.$field.compose_len()
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.$field.compose(buf)
}
}
impl<N: Compress> Compress for $target<N> {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
self.$field.compress(buf)
}
}
impl<N: Scan> Scan for $target<N> {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
N::scan(scanner).map(Self::new)
}
}
impl<N: fmt::Display> fmt::Display for $target<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}.", self.$field)
}
}
impl<N> RtypeRecordData for $target<N> {
const RTYPE: Rtype = Rtype::$rtype;
}
impl<N> ops::Deref for $target<N> {
type Target = N;
fn deref(&self) -> &Self::Target {
&self.$field
}
}
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct A {
addr: Ipv4Addr,
}
impl A {
pub fn new(addr: Ipv4Addr) -> A {
A { addr }
}
pub fn from_octets(a: u8, b: u8, c: u8, d: u8) -> A {
A::new(Ipv4Addr::new(a, b, c, d))
}
pub fn addr(&self) -> Ipv4Addr { self.addr }
pub fn set_addr(&mut self, addr: Ipv4Addr) { self.addr = addr }
}
impl From<Ipv4Addr> for A {
fn from(addr: Ipv4Addr) -> Self {
Self::new(addr)
}
}
impl From<A> for Ipv4Addr {
fn from(a: A) -> Self {
a.addr
}
}
impl FromStr for A {
type Err = <Ipv4Addr as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ipv4Addr::from_str(s).map(A::new)
}
}
impl Parse for A {
type Err = <Ipv4Addr as Parse>::Err;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
Ipv4Addr::parse(parser).map(Self::new)
}
fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
Ipv4Addr::skip(parser)?;
Ok(())
}
}
impl ParseAll for A {
type Err = <Ipv4Addr as ParseAll>::Err;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
Ipv4Addr::parse_all(parser, len).map(Self::new)
}
}
impl Compose for A {
fn compose_len(&self) -> usize {
4
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.addr.compose(buf)
}
}
impl Compress for A {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
buf.compose(self)
}
}
impl Scan for A {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
scanner.scan_string_phrase(|res| A::from_str(&res).map_err(Into::into))
}
}
impl fmt::Display for A {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.addr.fmt(f)
}
}
impl RtypeRecordData for A {
const RTYPE: Rtype = Rtype::A;
}
impl ops::Deref for A {
type Target = Ipv4Addr;
fn deref(&self) -> &Self::Target {
&self.addr
}
}
impl ops::DerefMut for A {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.addr
}
}
impl AsRef<Ipv4Addr> for A {
fn as_ref(&self) -> &Ipv4Addr {
&self.addr
}
}
impl AsMut<Ipv4Addr> for A {
fn as_mut(&mut self) -> &mut Ipv4Addr {
&mut self.addr
}
}
dname_type!(Cname, Cname, cname);
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Hinfo {
cpu: CharStr,
os: CharStr,
}
impl Hinfo {
pub fn new(cpu: CharStr, os: CharStr) -> Self {
Hinfo { cpu, os }
}
pub fn cpu(&self) -> &CharStr {
&self.cpu
}
pub fn os(&self) -> &CharStr {
&self.os
}
}
impl Parse for Hinfo {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
Ok(Self::new(CharStr::parse(parser)?, CharStr::parse(parser)?))
}
fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
CharStr::skip(parser)?;
CharStr::skip(parser)?;
Ok(())
}
}
impl ParseAll for Hinfo {
type Err = ParseAllError;
fn parse_all(parser: &mut Parser, len: usize)
-> Result<Self, Self::Err> {
let cpu = CharStr::parse(parser)?;
let len = match len.checked_sub(cpu.len() + 1) {
Some(len) => len,
None => return Err(ParseAllError::ShortField)
};
let os = CharStr::parse_all(parser, len)?;
Ok(Hinfo::new(cpu, os))
}
}
impl Compose for Hinfo {
fn compose_len(&self) -> usize {
self.cpu.compose_len() + self.os.compose_len()
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.cpu.compose(buf);
self.os.compose(buf);
}
}
impl Compress for Hinfo {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
buf.compose(self)
}
}
impl Scan for Hinfo {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
Ok(Self::new(CharStr::scan(scanner)?, CharStr::scan(scanner)?))
}
}
impl fmt::Display for Hinfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.cpu, self.os)
}
}
impl RtypeRecordData for Hinfo {
const RTYPE: Rtype = Rtype::Hinfo;
}
dname_type!(Mb, Mb, madname);
dname_type!(Md, Md, madname);
dname_type!(Mf, Mf, madname);
dname_type!(Mg, Mg, madname);
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Minfo<N=ParsedDname> {
rmailbx: N,
emailbx: N,
}
impl<N> Minfo<N> {
pub fn new(rmailbx: N, emailbx: N) -> Self {
Minfo { rmailbx, emailbx }
}
pub fn rmailbx(&self) -> &N {
&self.rmailbx
}
pub fn emailbx(&self) -> &N {
&self.emailbx
}
}
impl<N: Parse> Parse for Minfo<N> {
type Err = N::Err;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
Ok(Self::new(N::parse(parser)?, N::parse(parser)?))
}
fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
N::skip(parser)?;
N::skip(parser)?;
Ok(())
}
}
impl<N: Parse + ParseAll> ParseAll for Minfo<N>
where <N as ParseAll>::Err: From<<N as Parse>::Err> + From<ShortBuf> {
type Err = <N as ParseAll>::Err;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
let pos = parser.pos();
let rmailbx = N::parse(parser)?;
let rlen = parser.pos() - pos;
let len = if len <= rlen {
parser.seek(pos)?;
0
}
else {
len - rlen
};
let emailbx = N::parse_all(parser, len)?;
Ok(Self::new(rmailbx, emailbx))
}
}
impl<N: Compose> Compose for Minfo<N> {
fn compose_len(&self) -> usize {
self.rmailbx.compose_len() + self.emailbx.compose_len()
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.rmailbx.compose(buf);
self.emailbx.compose(buf);
}
}
impl<N: Compress> Compress for Minfo<N> {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
self.rmailbx.compress(buf)?;
self.emailbx.compress(buf)
}
}
impl<N: Scan> Scan for Minfo<N> {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
Ok(Self::new(N::scan(scanner)?, N::scan(scanner)?))
}
}
impl<N: fmt::Display> fmt::Display for Minfo<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}. {}.", self.rmailbx, self.emailbx)
}
}
impl<N> RtypeRecordData for Minfo<N> {
const RTYPE: Rtype = Rtype::Minfo;
}
dname_type!(Mr, Mr, newname);
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Mx<N=ParsedDname> {
preference: u16,
exchange: N,
}
impl<N> Mx<N> {
pub fn new(preference: u16, exchange: N) -> Self {
Mx { preference, exchange }
}
pub fn preference(&self) -> u16 {
self.preference
}
pub fn exchange(&self) -> &N {
&self.exchange
}
}
impl<N: Parse> Parse for Mx<N>
where N::Err: From<ShortBuf> {
type Err = N::Err;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
Ok(Self::new(u16::parse(parser)?, N::parse(parser)?))
}
fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
u16::skip(parser)?;
N::skip(parser)
}
}
impl<N: ParseAll> ParseAll for Mx<N>
where N::Err: From<ParseOpenError> + From<ShortBuf> {
type Err = N::Err;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 3 {
return Err(ParseOpenError::ShortField.into())
}
Ok(Self::new(u16::parse(parser)?, N::parse_all(parser, len - 2)?))
}
}
impl<N: Compose> Compose for Mx<N> {
fn compose_len(&self) -> usize {
self.exchange.compose_len() + 2
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.preference.compose(buf);
self.exchange.compose(buf);
}
}
impl<N: Compress> Compress for Mx<N> {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
buf.compose(&self.preference)?;
self.exchange.compress(buf)
}
}
impl<N: Scan> Scan for Mx<N> {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
Ok(Self::new(u16::scan(scanner)?, N::scan(scanner)?))
}
}
impl<N: fmt::Display> fmt::Display for Mx<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}.", self.preference, self.exchange)
}
}
impl<N> RtypeRecordData for Mx<N> {
const RTYPE: Rtype = Rtype::Mx;
}
dname_type!(Ns, Ns, nsdname);
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Null {
data: Bytes,
}
impl Null {
pub fn new(data: Bytes) -> Self {
Null { data }
}
pub fn data(&self) -> &Bytes {
&self.data
}
}
impl From<Bytes> for Null {
fn from(data: Bytes) -> Self {
Self::new(data)
}
}
impl ParseAll for Null {
type Err = ShortBuf;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
parser.parse_bytes(len).map(Self::new)
}
}
impl Compose for Null {
fn compose_len(&self) -> usize {
self.data.len()
}
fn compose<B: BufMut>(&self, buf: &mut B) {
buf.put_slice(self.data.as_ref())
}
}
impl Compress for Null {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
buf.compose(self)
}
}
impl RtypeRecordData for Null {
const RTYPE: Rtype = Rtype::Null;
}
impl ops::Deref for Null {
type Target = Bytes;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl AsRef<Bytes> for Null {
fn as_ref(&self) -> &Bytes {
&self.data
}
}
impl AsRef<[u8]> for Null {
fn as_ref(&self) -> &[u8] {
self.data.as_ref()
}
}
impl fmt::Display for Null {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\\# {}", self.data().len())?;
for ch in self.data().iter() {
write!(f, " {:02x}", ch)?;
}
Ok(())
}
}
dname_type!(Ptr, Ptr, ptrdname);
impl<N> Ptr<N> {
pub fn into_ptrdname(self) -> N {
self.ptrdname
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd)]
pub struct Soa<N=ParsedDname> {
mname: N,
rname: N,
serial: Serial,
refresh: u32,
retry: u32,
expire: u32,
minimum:u32
}
impl<N> Soa<N> {
pub fn new(mname: N, rname: N, serial: Serial,
refresh: u32, retry: u32, expire: u32, minimum: u32) -> Self {
Soa { mname, rname, serial, refresh, retry, expire, minimum }
}
pub fn mname(&self) -> &N {
&self.mname
}
pub fn rname(&self) -> &N {
&self.rname
}
pub fn serial(&self) -> Serial {
self.serial
}
pub fn refresh(&self) -> u32 {
self.refresh
}
pub fn retry(&self) -> u32 {
self.retry
}
pub fn expire(&self) -> u32 {
self.expire
}
pub fn minimum(&self) -> u32 {
self.minimum
}
}
impl<N: Parse> Parse for Soa<N> where N::Err: From<ShortBuf> {
type Err = N::Err;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
Ok(Self::new(N::parse(parser)?, N::parse(parser)?,
Serial::parse(parser)?, u32::parse(parser)?,
u32::parse(parser)?, u32::parse(parser)?,
u32::parse(parser)?))
}
fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
N::skip(parser)?;
N::skip(parser)?;
Serial::skip(parser)?;
u32::skip(parser)?;
u32::skip(parser)?;
u32::skip(parser)?;
u32::skip(parser)?;
Ok(())
}
}
impl<N: ParseAll + Parse> ParseAll for Soa<N>
where <N as ParseAll>::Err: From<<N as Parse>::Err>,
<N as ParseAll>::Err: From<ParseAllError>,
<N as Parse>::Err: From<ShortBuf> {
type Err = <N as ParseAll>::Err;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
let mut tmp = parser.clone();
let res = <Self as Parse>::parse(&mut tmp)?;
if tmp.pos() - parser.pos() < len {
Err(ParseAllError::TrailingData.into())
}
else if tmp.pos() - parser.pos() > len {
Err(ParseAllError::ShortField.into())
}
else {
parser.advance(len)?;
Ok(res)
}
}
}
impl<N: Compose> Compose for Soa<N> {
fn compose_len(&self) -> usize {
self.mname.compose_len() + self.rname.compose_len() + (5 * 4)
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.mname.compose(buf);
self.rname.compose(buf);
self.serial.compose(buf);
self.refresh.compose(buf);
self.retry.compose(buf);
self.expire.compose(buf);
self.minimum.compose(buf);
}
}
impl<N: Compress> Compress for Soa<N> {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
self.mname.compress(buf)?;
self.rname.compress(buf)?;
buf.compose(&self.serial)?;
buf.compose(&self.refresh)?;
buf.compose(&self.retry)?;
buf.compose(&self.expire)?;
buf.compose(&self.minimum)
}
}
impl<N: Scan> Scan for Soa<N> {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
Ok(Self::new(N::scan(scanner)?, N::scan(scanner)?,
Serial::scan(scanner)?, u32::scan(scanner)?,
u32::scan(scanner)?, u32::scan(scanner)?,
u32::scan(scanner)?))
}
}
impl<N: fmt::Display> fmt::Display for Soa<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}. {}. {} {} {} {} {}",
self.mname, self.rname, self.serial, self.refresh, self.retry,
self.expire, self.minimum)
}
}
impl<N> RtypeRecordData for Soa<N> {
const RTYPE: Rtype = Rtype::Soa;
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Txt {
text: Bytes,
}
impl Txt {
pub fn new(text: CharStr) -> Self {
Txt { text: text.into_bytes() }
}
pub fn iter(&self) -> TxtIter {
TxtIter::new(self.text.clone())
}
pub fn text(&self) -> Bytes {
if self.text[0] as usize == self.text.len() + 1 {
self.text.slice_from(1)
}
else {
let mut res = BytesMut::with_capacity(self.text.len());
for item in self.iter() {
res.put_slice(item.as_ref());
}
res.freeze()
}
}
}
impl IntoIterator for Txt {
type Item = CharStr;
type IntoIter = TxtIter;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a Txt {
type Item = CharStr;
type IntoIter = TxtIter;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl ParseAll for Txt {
type Err = ParseOpenError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
let text = parser.parse_bytes(len)?;
let mut tmp = Parser::from_bytes(text.clone());
while tmp.remaining() > 0 {
CharStr::skip(&mut tmp).map_err(|_| ParseOpenError::ShortField)?
}
Ok(Txt { text })
}
}
impl Compose for Txt {
fn compose_len(&self) -> usize {
self.text.len()
}
fn compose<B: BufMut>(&self, buf: &mut B) {
buf.put_slice(self.text.as_ref())
}
}
impl Compress for Txt {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
buf.compose(self)
}
}
impl Scan for Txt {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
let first = CharStr::scan(scanner)?;
let second = match CharStr::scan(scanner) {
Err(_) => return Ok(Txt::new(first)),
Ok(second) => second,
};
let mut text = first.into_bytes();
text.extend_from_slice(second.as_ref());
while let Ok(some) = CharStr::scan(scanner) {
text.extend_from_slice(some.as_ref());
}
Ok(Txt { text })
}
}
impl fmt::Display for Txt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut items = self.iter();
match items.next() {
Some(item) => item.fmt(f)?,
None => return Ok(())
}
for item in items {
write!(f, " {}", item)?;
}
Ok(())
}
}
impl RtypeRecordData for Txt {
const RTYPE: Rtype = Rtype::Txt;
}
#[derive(Clone, Debug)]
pub struct TxtIter {
parser: Parser,
}
impl TxtIter {
fn new(text: Bytes)-> Self {
TxtIter { parser: Parser::from_bytes(text) }
}
}
impl Iterator for TxtIter {
type Item = CharStr;
fn next(&mut self) -> Option<Self::Item> {
if self.parser.remaining() == 0 {
None
}
else {
Some(CharStr::parse(&mut self.parser).unwrap())
}
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Wks {
address: Ipv4Addr,
protocol: u8,
bitmap: Bytes,
}
impl Wks {
pub fn new(address: Ipv4Addr, protocol: u8, bitmap: Bytes) -> Self {
Wks { address, protocol, bitmap }
}
pub fn address(&self) -> Ipv4Addr {
self.address
}
pub fn protocol(&self) -> u8 {
self.protocol
}
pub fn bitmap(&self) -> &Bytes {
&self.bitmap
}
pub fn serves(&self, port: u16) -> bool {
let octet = (port / 8) as usize;
let bit = (port % 8) as usize;
match self.bitmap.get(octet) {
Some(x) => (x >> bit) > 0,
None => false
}
}
pub fn iter(&self) -> WksIter {
WksIter::new(self.bitmap.clone())
}
}
impl ParseAll for Wks {
type Err = ParseOpenError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 5 {
return Err(ParseOpenError::ShortField)
}
Ok(Self::new(Ipv4Addr::parse(parser)?, u8::parse(parser)?,
parser.parse_bytes(len - 5)?))
}
}
impl Compose for Wks {
fn compose_len(&self) -> usize {
self.bitmap.len() + 5
}
fn compose<B: BufMut>(&self, buf: &mut B) {
self.address.compose(buf);
self.protocol.compose(buf);
self.bitmap.compose(buf);
}
}
impl Compress for Wks {
fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
buf.compose(self)
}
}
impl Scan for Wks {
fn scan<C: CharSource>(scanner: &mut Scanner<C>)
-> Result<Self, ScanError> {
let address = scanner.scan_string_phrase(|res| {
Ipv4Addr::from_str(&res).map_err(Into::into)
})?;
let protocol = u8::scan(scanner)?;
let mut builder = WksBuilder::new(address, protocol);
while let Ok(service) = u16::scan(scanner) {
builder.add_service(service)
}
Ok(builder.finish())
}
}
impl fmt::Display for Wks {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.address, self.protocol)?;
for service in self.iter() {
write!(f, " {}", service)?;
}
Ok(())
}
}
impl RtypeRecordData for Wks {
const RTYPE: Rtype = Rtype::Wks;
}
#[derive(Clone, Debug)]
pub struct WksIter {
bitmap: Bytes,
octet: usize,
bit: usize
}
impl WksIter {
fn new(bitmap: Bytes) -> Self {
WksIter { bitmap, octet: 0, bit: 0 }
}
fn serves(&self) -> bool {
(self.bitmap[self.octet] >> self.bit) > 0
}
}
impl Iterator for WksIter {
type Item = u16;
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.octet >= self.bitmap.len() { return None }
else {
if self.serves() {
return Some((self.octet * 8 + self.bit) as u16)
}
if self.bit == 7 { self.octet += 1; self.bit = 0 }
else { self.bit += 1 }
}
}
}
}
#[derive(Clone, Debug)]
pub struct WksBuilder {
address: Ipv4Addr,
protocol: u8,
bitmap: BytesMut,
}
impl WksBuilder {
pub fn new(address: Ipv4Addr, protocol: u8) -> Self {
WksBuilder { address, protocol, bitmap: BytesMut::new() }
}
pub fn add_service(&mut self, service: u16) {
let octet = (service >> 2) as usize;
let bit = 1 << (service & 0x3);
while self.bitmap.len() < octet + 1 {
self.bitmap.extend_from_slice(b"0")
}
self.bitmap[octet] |= bit;
}
pub fn finish(self) -> Wks {
Wks::new(self.address, self.protocol, self.bitmap.freeze())
}
}
pub mod parsed {
use ::bits::name::ParsedDname;
pub use super::A;
pub type Cname = super::Cname<ParsedDname>;
pub use super::Hinfo;
pub type Mb = super::Mb<ParsedDname>;
pub type Md = super::Md<ParsedDname>;
pub type Mf = super::Mf<ParsedDname>;
pub type Mg = super::Mg<ParsedDname>;
pub type Minfo = super::Minfo<ParsedDname>;
pub type Mr = super::Mr<ParsedDname>;
pub type Mx = super::Mx<ParsedDname>;
pub type Ns = super::Ns<ParsedDname>;
pub use super::Null;
pub type Ptr = super::Ptr<ParsedDname>;
pub type Soa = super::Soa<ParsedDname>;
pub use super::Txt;
pub use super::Wks;
}