xidl-xcdr 0.2.0

A IDL codegen.
Documentation
use crate::XcdrDeserializer;

use crate::{
    ffi::{XcdrFfiError, macros::impl_ffi_deserialize_for},
    plcdr2::Plcdr2Deserializer,
};

#[repr(C)]
pub struct FfiPlcdr2Deserializer {
    buf_ptr: *const u8,
    buf_len: usize,
    pos: usize,
}

impl FfiPlcdr2Deserializer {
    fn deserializer_buf(&self) -> Result<&[u8], XcdrFfiError> {
        if self.buf_ptr.is_null() && self.buf_len != 0 {
            return Err(XcdrFfiError::NullPointer);
        }
        Ok(unsafe { std::slice::from_raw_parts(self.buf_ptr, self.buf_len) })
    }

    #[unsafe(no_mangle)]
    pub extern "C" fn plcdr2_deserializer_new(buf_ptr: *const u8, buf_len: usize) -> Self {
        FfiPlcdr2Deserializer {
            buf_ptr,
            buf_len,
            pos: 0,
        }
    }

    #[unsafe(no_mangle)]
    pub extern "C" fn plcdr2_deserializer_position(&self) -> usize {
        self.pos
    }

    #[unsafe(no_mangle)]
    pub extern "C" fn plcdr2_deserializer_reset(&mut self) {
        self.pos = 0;
    }

    #[unsafe(no_mangle)]
    pub extern "C" fn plcdr2_deserializer_read_dheader(&mut self, out: *mut u32) -> XcdrFfiError {
        if out.is_null() {
            return XcdrFfiError::NullPointer;
        }
        match with_deserializer(self, |de| de.read_dheader()) {
            Ok(val) => {
                unsafe { *out = val };
                XcdrFfiError::Ok
            }
            Err(err) => err,
        }
    }

    #[unsafe(no_mangle)]
    pub extern "C" fn plcdr2_deserializer_read_emheader(&mut self, out: *mut u32) -> XcdrFfiError {
        if out.is_null() {
            return XcdrFfiError::NullPointer;
        }
        match with_deserializer(self, |de| de.read_emheader()) {
            Ok(val) => {
                unsafe { *out = val };
                XcdrFfiError::Ok
            }
            Err(err) => err,
        }
    }
}

impl_ffi_deserialize_for!(
    plcdr2_deserializer,
    FfiPlcdr2Deserializer,
    with_deserializer
);

fn with_deserializer<R>(
    self_: &mut FfiPlcdr2Deserializer,
    f: impl FnOnce(&mut Plcdr2Deserializer<'_>) -> crate::error::XcdrResult<R>,
) -> Result<R, XcdrFfiError> {
    let pos = self_.pos;
    let buf = FfiPlcdr2Deserializer::deserializer_buf(self_)?;
    let mut de = Plcdr2Deserializer::new(buf);
    de.set_position(pos);
    let out = f(&mut de)?;
    self_.pos = de.position();
    Ok(out)
}