flex-dns 1.0.1

A no alloc no std DNS parser and serializer written in Rust.
Documentation
use crate::{DnsError, DnsMessageError};

pub(crate) trait ParseData<'a> {
    fn parse_data(&self) -> &'a [u8];
}

impl<'a> ParseData<'a> for &'a [u8] {
    #[inline(always)]
    fn parse_data(&self) -> &'a [u8] {
        *self
    }
}

pub(crate) trait Parse<'a>: Sized {
    fn parse<T: ParseData<'a>>(bytes: T, i: &mut usize) -> Result<Self, DnsMessageError>;
}

impl<'a, S: ParseBytes<'a>> Parse<'a> for S {
    #[inline(always)]
    fn parse<T: ParseData<'a>>(bytes: T, i: &mut usize) -> Result<Self, DnsMessageError> {
        Self::parse_bytes(bytes.parse_data(), i)
    }
}

pub(crate) trait ParseBytes<'a>: Sized {
    fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError>;
}

impl<'a> ParseBytes<'a> for u8 {
    #[inline]
    fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError> {
        if bytes.len() < *i + 1 {
            return Err(DnsMessageError::DnsError(DnsError::UnexpectedEndOfBuffer));
        }

        let value = bytes[*i];
        *i += 1;

        Ok(value)
    }
}

impl<'a> ParseBytes<'a> for u16 {
    #[inline]
    fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError> {
        if bytes.len() < *i + 2 {
            return Err(DnsMessageError::DnsError(DnsError::UnexpectedEndOfBuffer));
        }

        let value = u16::from_be_bytes([
            bytes[*i],
            bytes[*i + 1]
        ]);
        *i += 2;

        Ok(value)
    }
}

impl<'a> ParseBytes<'a> for u32 {
    #[inline]
    fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError> {
        if bytes.len() < *i + 4 {
            return Err(DnsMessageError::DnsError(DnsError::UnexpectedEndOfBuffer));
        }

        let value = u32::from_be_bytes([
            bytes[*i],
            bytes[*i + 1],
            bytes[*i + 2],
            bytes[*i + 3]
        ]);
        *i += 4;

        Ok(value)
    }
}

impl<'a> ParseBytes<'a> for u64 {
    #[inline]
    fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError> {
        if bytes.len() < *i + 8 {
            return Err(DnsMessageError::DnsError(DnsError::UnexpectedEndOfBuffer));
        }

        let value = u64::from_be_bytes([
            bytes[*i],
            bytes[*i + 1],
            bytes[*i + 2],
            bytes[*i + 3],
            bytes[*i + 4],
            bytes[*i + 5],
            bytes[*i + 6],
            bytes[*i + 7]
        ]);
        *i += 8;

        Ok(value)
    }
}

impl<'a, const SIZE: usize> ParseBytes<'a> for [u8; SIZE] {
    #[inline]
    fn parse_bytes(bytes: &'a [u8], i: &mut usize) -> Result<Self, DnsMessageError> {
        if bytes.len() < *i + SIZE {
            return Err(DnsMessageError::DnsError(DnsError::UnexpectedEndOfBuffer));
        }

        let mut value = [0u8; SIZE];
        value.copy_from_slice(&bytes[*i..*i + SIZE]);
        *i += SIZE;

        Ok(value)
    }
}