servicepoint_binding_c 0.15.0

C bindings for the servicepoint crate.
Documentation
//! FFI slice helper

/// Represents a span of memory (`&mut [u8]` ) as a struct.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - accesses to the memory pointed to with `start` is never accessed outside `length`
/// - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in
///   the function returning this type.
/// - if `start` is NULL or `length` is 0, do not dereference `start`.
///
/// # Examples
///
/// ```c
/// ByteSlice empty = {.start: NULL, .length = 0};
/// ```
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ByteSlice {
    /// The start address of the memory.
    pub start: *mut u8,
    /// The amount of memory in bytes.
    pub length: usize,
}

impl ByteSlice {
    /// Represents an invalid [ByteSlice] instance.
    pub const INVALID: ByteSlice = ByteSlice {
        start: std::ptr::null_mut(),
        length: 0,
    };

    pub(crate) unsafe fn as_slice(&self) -> &[u8] {
        assert!(!self.start.is_null());
        unsafe { std::slice::from_raw_parts(self.start, self.length) }
    }

    #[allow(
        clippy::mut_from_ref,
        reason = "This is used to get a pointer from the C side."
    )]
    pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] {
        unsafe { std::slice::from_raw_parts_mut(self.start, self.length) }
    }

    pub(crate) unsafe fn from_slice(slice: &mut [u8]) -> Self {
        Self {
            start: slice.as_mut_ptr(),
            length: slice.len(),
        }
    }
}