rsdns 0.23.0

DNS Client Library
Documentation
use crate::{Error, Result};

#[derive(Debug)]
pub struct WCursor<'a> {
    buf: &'a mut [u8],
    pos: usize,
}

impl<'a> WCursor<'a> {
    #[inline]
    pub fn new(buf: &'a mut [u8]) -> Self {
        Self { buf, pos: 0 }
    }

    #[inline]
    pub fn pos(&self) -> usize {
        self.pos
    }

    #[inline]
    pub fn reset_pos(&mut self) -> usize {
        let mut new_pos = 0;
        std::mem::swap(&mut self.pos, &mut new_pos);
        new_pos
    }

    #[inline]
    pub fn len(&self) -> usize {
        let capacity = self.capacity();
        capacity.saturating_sub(self.pos)
    }

    #[inline]
    pub fn capacity(&self) -> usize {
        self.buf.len()
    }

    #[inline]
    pub fn slice(&mut self, size: usize) -> Result<&mut [u8]> {
        if self.len() >= size {
            Ok(unsafe { self.buf.get_unchecked_mut(self.pos..self.pos + size) })
        } else {
            Err(Error::BufferTooShort(self.pos() + size))
        }
    }

    #[inline]
    pub fn u16_be(&mut self, val: u16) -> Result<()> {
        w_be!(self, u16, val)
    }

    #[inline]
    pub fn u32_be(&mut self, val: u32) -> Result<()> {
        w_be!(self, u32, val)
    }

    #[inline]
    pub unsafe fn u16_be_unchecked(&mut self, val: u16) {
        wu_be!(self, u16, val)
    }

    #[inline]
    pub fn u8(&mut self, val: u8) -> Result<()> {
        unsafe {
            *self.slice(1)?.get_unchecked_mut(0) = val;
        }
        self.pos += 1;
        Ok(())
    }

    #[inline]
    pub unsafe fn u8_unchecked(&mut self, val: u8) {
        unsafe {
            *self.buf.get_unchecked_mut(self.pos) = val;
        }
        self.pos += 1;
    }

    #[inline]
    pub unsafe fn bytes_unchecked(&mut self, buf: &[u8]) {
        unsafe {
            self.buf
                .get_unchecked_mut(self.pos..self.pos + buf.len())
                .copy_from_slice(buf);
        }
        self.pos += buf.len();
    }
}