flat_message 0.2.1

Zero-copy, schema-less serialization and deserialization fast library for Rust.
Documentation
use super::SerDe;
use super::SerDeSlice;
use super::SerDeVec;
use super::SerDeVecType;
use crate::size;
use crate::common::data_format::DataFormat;
use std::ptr;

unsafe impl SerDe<'_> for bool {
    const DATA_FORMAT: DataFormat = DataFormat::Bool;
    #[inline(always)]
    unsafe fn from_buffer_unchecked(buf: &[u8], pos: usize) -> Self {
        unsafe {
            let ptr = buf.as_ptr().add(pos);
            !matches!(*ptr, 0)
        }
    }
    fn from_buffer(buf: &[u8], pos: usize) -> Option<Self> {
        unsafe {
            let ptr = buf.as_ptr().add(pos);
            match *ptr {
                0 => Some(false),
                1 => Some(true),
                _ => None,
            }
        }
    }
    #[inline(always)]
    unsafe fn write(value: &Self, p: *mut u8, pos: usize) -> usize {
        unsafe {
            ptr::write_unaligned(p.add(pos), *value as u8);
            pos + 1
        }
    }
    #[inline(always)]
    fn size(_: &Self) -> usize {
        1
    }
}

unsafe impl<'a> SerDeSlice<'a> for bool {
    const DATA_FORMAT: DataFormat = DataFormat::Bool;
    #[inline(always)]
    unsafe fn from_buffer_unchecked(buf: &[u8], pos: usize) -> &'a [Self] {
        let p = buf.as_ptr();
        let (len, buf_len) = size::read_unchecked(p, pos, size::Format::U8withExtension);
        std::slice::from_raw_parts(p.add(pos + buf_len) as *const bool, len)
    }

    #[inline(always)]
    fn from_buffer(buf: &'a [u8], pos: usize) -> Option<&'a [Self]> {
        let (len, buf_len) =
            unsafe { size::read(buf.as_ptr(), pos, buf.len(), size::Format::U8withExtension)? };
        let end = pos + buf_len + len;
        if end > buf.len() {
            None
        } else {
            let slice = unsafe {
                std::slice::from_raw_parts(buf.as_ptr().add(pos + buf_len), len)
            };
            for &b in slice {
                if b > 1 {
                    return None;
                }
            }
            Some(unsafe {
                std::slice::from_raw_parts(buf.as_ptr().add(pos + buf_len) as *const bool, len)
            })
        }
    }
    #[inline(always)]
    unsafe fn write(obj: &[Self], p: *mut u8, pos: usize) -> usize {
        let len = obj.len() as u32;
        unsafe {
            let buf_len = size::write(p, pos, len, size::Format::U8withExtension);
            std::ptr::copy_nonoverlapping(obj.as_ptr() as *mut u8, p.add(pos + buf_len), obj.len());
            pos + buf_len + len as usize
        }
    }
    #[inline(always)]
    fn size(obj: &[Self]) -> usize {
        size::len(obj.len() as u32, size::Format::U8withExtension) + obj.len()
    }
}

unsafe impl<TVecType: SerDeVecType<bool>> SerDeVec<'_, TVecType> for bool {
    const DATA_FORMAT: DataFormat = DataFormat::Bool;
    #[inline(always)]
    unsafe fn from_buffer_unchecked(buf: &[u8], pos: usize) -> TVecType {
        let res: &[bool] = SerDeSlice::from_buffer_unchecked(buf, pos);
        TVecType::from_slice(res)
    }
    #[inline(always)]
    fn from_buffer(buf: &[u8], pos: usize) -> Option<TVecType> {
        let res: &[bool] = SerDeSlice::from_buffer(buf, pos)?;
        Some(TVecType::from_slice(res))
    }
    #[inline(always)]
    unsafe fn write(obj: &TVecType, p: *mut u8, pos: usize) -> usize {
        SerDeSlice::write(obj.as_slice(), p, pos)
    }
    #[inline(always)]
    fn size(obj: &TVecType) -> usize {
        size::len(obj.len() as u32, size::Format::U8withExtension) + obj.len()
    }
}