safa_abi/raw/
mod.rs

1pub mod io;
2pub mod processes;
3
4use core::ptr::NonNull;
5
6#[repr(C)]
7#[derive(Debug, Clone, Copy)]
8/// A C compatible slice of type `T`
9pub struct RawSlice<T> {
10    ptr: *const T,
11    len: usize,
12}
13
14impl<T> RawSlice<T> {
15    #[inline(always)]
16    pub unsafe fn from_raw_parts(ptr: *const T, len: usize) -> Self {
17        Self { ptr, len }
18    }
19    #[inline(always)]
20    pub unsafe fn from_slice(slice: &[T]) -> Self {
21        Self {
22            ptr: slice.as_ptr(),
23            len: slice.len(),
24        }
25    }
26
27    #[inline(always)]
28    pub fn len(&self) -> usize {
29        self.len
30    }
31
32    #[inline(always)]
33    pub fn as_ptr(&self) -> *const T {
34        self.ptr
35    }
36
37    /// Converts a [`RawSlice<T>`] into a slice of type `T`
38    ///
39    /// returns `None` if the slice ptr is null or the length is zero
40    /// # Safety
41    ///
42    /// panics if the slice ptr is not aligned to the alignment of `T`
43    #[inline(always)]
44    pub unsafe fn into_slice<'a>(self) -> Option<&'a [T]> {
45        if self.ptr.is_null() || self.len == 0 {
46            None
47        } else {
48            Some(core::slice::from_raw_parts(self.ptr, self.len))
49        }
50    }
51}
52
53impl<T> RawSliceMut<T> {
54    #[inline(always)]
55    pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
56        Self { ptr, len }
57    }
58
59    #[inline(always)]
60    pub fn len(&self) -> usize {
61        self.len
62    }
63
64    #[inline(always)]
65    pub fn as_ptr(&self) -> *const T {
66        self.ptr
67    }
68
69    #[inline(always)]
70    pub fn as_mut_ptr(&self) -> *mut T {
71        self.ptr
72    }
73
74    /// Converts a [`RawSliceMut<T>`] into a slice of type `T`
75    ///
76    /// returns `None` if the slice ptr is null or the length is zero
77    /// # Safety
78    ///
79    /// panics if the slice ptr is not aligned to the alignment of `T`
80    #[inline(always)]
81    pub unsafe fn into_slice_mut<'a>(self) -> Option<&'a mut [T]> {
82        if self.ptr.is_null() || self.len == 0 {
83            None
84        } else {
85            Some(core::slice::from_raw_parts_mut(self.ptr, self.len))
86        }
87    }
88}
89
90impl<T> RawSliceMut<RawSlice<T>> {
91    /// Converts a slice of slices of [`T`] into [`RawSliceMut<RawSlice<T>>`]
92    /// # Safety
93    /// `slices` becomes invalid after use
94    /// as it is going to be reused as a memory location for creating `Self`
95    /// making this unexpensive but dangerous
96    /// O(N) expect if the Layout of RawSlice is equal to the Layout of rust slices, and it has been optimized it is O(1)
97    #[inline(always)]
98    pub unsafe fn from_slices(slices: *mut [&[T]]) -> Self {
99        let old_slices = unsafe { &mut *slices };
100        let raw_slices = unsafe { &mut *(slices as *mut [RawSlice<T>]) };
101
102        for (i, slice) in old_slices.iter().enumerate() {
103            raw_slices[i] = unsafe { RawSlice::from_slice(slice) };
104        }
105        unsafe { RawSliceMut::from_raw_parts(raw_slices.as_mut_ptr(), raw_slices.len()) }
106    }
107}
108
109#[repr(C)]
110#[derive(Debug, Clone, Copy)]
111/// A C complitable mutable slice of type `T`
112pub struct RawSliceMut<T> {
113    ptr: *mut T,
114    len: usize,
115}
116
117#[repr(C)]
118#[derive(Debug, Clone, Copy)]
119pub struct NonNullSlice<T> {
120    ptr: NonNull<T>,
121    len: usize,
122}
123
124impl<T> NonNullSlice<T> {
125    pub const unsafe fn from_raw_parts(ptr: NonNull<T>, len: usize) -> Self {
126        Self { ptr, len }
127    }
128
129    pub const fn as_non_null(&self) -> NonNull<T> {
130        self.ptr
131    }
132
133    pub const fn as_ptr(&self) -> *mut T {
134        self.ptr.as_ptr()
135    }
136
137    pub const fn len(&self) -> usize {
138        self.len
139    }
140
141    /// Converts a [`NonNullSlice<T>`] into a slice of type `T`
142    /// # Safety
143    /// panics if the slice ptr is not aligned to the alignment of `T`
144    #[inline(always)]
145    pub unsafe fn into_slice_mut<'a>(self) -> &'a mut [T] {
146        unsafe { core::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
147    }
148}
149
150/// A C complitable Option-like type
151#[derive(Debug)]
152#[repr(C)]
153pub enum Optional<T> {
154    None,
155    Some(T),
156}
157
158impl<T> Default for Optional<T> {
159    fn default() -> Self {
160        Self::None
161    }
162}
163
164impl<T> From<Option<T>> for Optional<T> {
165    #[inline(always)]
166    fn from(value: Option<T>) -> Self {
167        match value {
168            None => Self::None,
169            Some(x) => Self::Some(x),
170        }
171    }
172}
173
174impl<T> From<Optional<T>> for Option<T> {
175    #[inline(always)]
176    fn from(value: Optional<T>) -> Self {
177        match value {
178            Optional::None => None,
179            Optional::Some(x) => Some(x),
180        }
181    }
182}
183
184impl<T: Clone> Clone for Optional<T> {
185    #[inline(always)]
186    fn clone(&self) -> Self {
187        match self {
188            Self::None => Self::None,
189            Self::Some(x) => Self::Some(x.clone()),
190        }
191    }
192}
193impl<T: Copy> Copy for Optional<T> {}
194
195impl<T: PartialEq> PartialEq for Optional<T> {
196    #[inline(always)]
197    fn eq(&self, other: &Self) -> bool {
198        match (self, other) {
199            (Self::None, Self::None) => true,
200            (Self::Some(x), Self::Some(y)) => x == y,
201            _ => false,
202        }
203    }
204}
205
206impl<T: Eq> Eq for Optional<T> {}