dns-message-parser 0.9.0

Libary to encode and decode DNS packets
Documentation
use crate::{DecodeError, DecodeResult};
use bytes::Bytes;
use std::cmp::Ordering;

pub(crate) struct Decoder<'a, 'b: 'a> {
    pub parent: Option<&'a Decoder<'b, 'b>>,
    pub(super) bytes: Bytes,
    pub(super) offset: usize,
}

impl<'a, 'b: 'a> Decoder<'b, 'b> {
    pub(super) fn sub(&'a mut self, sub_length: u16) -> DecodeResult<Decoder<'a, 'b>> {
        let bytes = self.read(sub_length as usize)?;
        let decoder = Decoder::<'a, 'b> {
            parent: Some(self),
            bytes,
            offset: 0,
        };
        Ok(decoder)
    }
}

impl<'a, 'b: 'a> Decoder<'a, 'b> {
    pub(crate) const fn main(bytes: Bytes) -> Decoder<'static, 'static> {
        Decoder {
            parent: None,
            bytes,
            offset: 0,
        }
    }

    pub(super) fn new_main_offset(&self, offset: u16) -> Decoder<'static, 'static> {
        let main = self.get_main();
        Decoder {
            parent: None,
            bytes: main.bytes.clone(),
            offset: offset as usize,
        }
    }

    pub(super) const fn get_main(&self) -> &Decoder<'a, 'b> {
        let mut root = self;
        loop {
            match root.parent {
                Some(parent) => root = parent,
                None => return root,
            }
        }
    }

    pub(super) fn is_finished(&self) -> DecodeResult<bool> {
        let bytes_len = self.bytes.len();
        match self.offset.cmp(&bytes_len) {
            Ordering::Less => Ok(false),
            Ordering::Equal => Ok(true),
            Ordering::Greater => Err(DecodeError::NotEnoughBytes(bytes_len, self.offset)),
        }
    }

    pub(super) fn remaining(&self) -> DecodeResult<usize> {
        let bytes_len = self.bytes.len();
        match bytes_len.checked_sub(self.offset) {
            Some(remaining) => Ok(remaining),
            None => Err(DecodeError::NotEnoughBytes(bytes_len, self.offset)),
        }
    }

    pub(super) fn finished(self) -> DecodeResult<()> {
        match self.is_finished()? {
            true => Ok(()),
            false => Err(DecodeError::TooManyBytes(self.bytes.len(), self.offset)),
        }
    }

    pub(super) fn read(&mut self, length: usize) -> DecodeResult<Bytes> {
        let start = self.offset;
        self.offset += length;
        if self.offset <= self.bytes.len() {
            Ok(self.bytes.slice(start..self.offset))
        } else {
            Err(DecodeError::NotEnoughBytes(self.bytes.len(), self.offset))
        }
    }
}