nstd_sys/
lib.rs

1#![doc = include_str!("../README.md")]
2#![warn(
3    deprecated_in_future,
4    ffi_unwind_calls,
5    future_incompatible,
6    invalid_reference_casting,
7    let_underscore,
8    macro_use_extern_crate,
9    meta_variable_misuse,
10    missing_abi,
11    missing_copy_implementations,
12    missing_docs,
13    non_ascii_idents,
14    nonstandard_style,
15    noop_method_call,
16    rust_2018_compatibility,
17    rust_2018_idioms,
18    rust_2021_compatibility,
19    single_use_lifetimes,
20    trivial_casts,
21    trivial_numeric_casts,
22    unreachable_pub,
23    unused,
24    unused_import_braces,
25    unused_lifetimes,
26    unused_qualifications,
27    unused_tuple_struct_fields,
28    variant_size_differences,
29    clippy::all,
30    clippy::cargo,
31    clippy::complexity,
32    clippy::correctness,
33    clippy::nursery,
34    clippy::pedantic,
35    clippy::perf,
36    clippy::style,
37    clippy::suspicious,
38    // clippy::restriction:
39    clippy::alloc_instead_of_core,
40    clippy::arithmetic_side_effects,
41    clippy::missing_docs_in_private_items,
42    clippy::std_instead_of_alloc,
43    clippy::std_instead_of_core,
44    clippy::undocumented_unsafe_blocks,
45    clippy::unnecessary_safety_comment,
46    clippy::unnecessary_safety_doc,
47    clippy::unneeded_field_pattern,
48)]
49#![allow(
50    clippy::match_bool,
51    clippy::module_name_repetitions,
52    clippy::must_use_candidate,
53    clippy::needless_pass_by_ref_mut,
54    clippy::redundant_pub_crate,
55    clippy::significant_drop_in_scrutinee
56)]
57#![cfg_attr(feature = "link", allow(dead_code, unused_imports))]
58#![cfg_attr(not(any(test, feature = "std")), no_std)]
59#![cfg_attr(doc_cfg, feature(doc_cfg))]
60#[cfg(feature = "alloc")]
61#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
62pub mod alloc;
63#[cfg(feature = "core")]
64#[cfg_attr(doc_cfg, doc(cfg(feature = "core")))]
65pub mod core;
66#[cfg(feature = "cstring")]
67#[cfg_attr(doc_cfg, doc(cfg(feature = "cstring")))]
68pub mod cstring;
69#[cfg(feature = "env")]
70#[cfg_attr(doc_cfg, doc(cfg(feature = "env")))]
71pub mod env;
72#[cfg(feature = "fs")]
73#[cfg_attr(doc_cfg, doc(cfg(feature = "fs")))]
74pub mod fs;
75#[cfg(feature = "heap_ptr")]
76#[cfg_attr(doc_cfg, doc(cfg(feature = "heap_ptr")))]
77pub mod heap_ptr;
78#[cfg(feature = "io")]
79#[cfg_attr(doc_cfg, doc(cfg(feature = "io")))]
80pub mod io;
81#[cfg(feature = "math")]
82#[cfg_attr(doc_cfg, doc(cfg(feature = "math")))]
83pub mod math;
84#[cfg(feature = "mutex")]
85#[cfg_attr(doc_cfg, doc(cfg(feature = "mutex")))]
86pub mod mutex;
87#[cfg(feature = "os")]
88#[cfg_attr(doc_cfg, doc(cfg(feature = "os")))]
89pub mod os;
90#[cfg(feature = "proc")]
91#[cfg_attr(doc_cfg, doc(cfg(feature = "proc")))]
92pub mod proc;
93#[cfg(feature = "shared_lib")]
94#[cfg_attr(doc_cfg, doc(cfg(feature = "shared_lib")))]
95pub mod shared_lib;
96#[cfg(feature = "shared_ptr")]
97#[cfg_attr(doc_cfg, doc(cfg(feature = "shared_ptr")))]
98pub mod shared_ptr;
99#[cfg(feature = "string")]
100#[cfg_attr(doc_cfg, doc(cfg(feature = "string")))]
101pub mod string;
102#[cfg(test)]
103pub(crate) mod test;
104#[cfg(feature = "thread")]
105#[cfg_attr(doc_cfg, doc(cfg(feature = "thread")))]
106pub mod thread;
107#[cfg(feature = "time")]
108#[cfg_attr(doc_cfg, doc(cfg(feature = "time")))]
109pub mod time;
110#[cfg(feature = "timed_mutex")]
111#[cfg_attr(doc_cfg, doc(cfg(feature = "timed_mutex")))]
112pub mod timed_mutex;
113#[cfg(feature = "vec")]
114#[cfg_attr(doc_cfg, doc(cfg(feature = "vec")))]
115pub mod vec;
116use ::core::{
117    ffi::{c_char, c_void},
118    marker::PhantomData,
119    ops::{Deref, DerefMut},
120    ptr::{addr_of, addr_of_mut},
121};
122
123/// [`NSTDInt`]'s maximum value represented as [`NSTDUInt`].
124#[allow(dead_code)]
125const NSTD_INT_MAX: NSTDUInt = NSTDInt::MAX as _;
126
127/// A null pointer value constant.
128pub const NSTD_NULL: NSTDAnyMut = ::core::ptr::null_mut();
129
130/// Boolean value false (0).
131pub const NSTD_FALSE: NSTDBool = false;
132/// Boolean value true (1).
133pub const NSTD_TRUE: NSTDBool = true;
134
135/// An integral type who's size matches the target architecture's pointer size.
136pub type NSTDInt = isize;
137/// An unsigned integral type who's size matches the target architecture's pointer size.
138pub type NSTDUInt = usize;
139
140/// An 8-bit signed integer type.
141pub type NSTDInt8 = i8;
142/// An 8-bit unsigned integer type.
143pub type NSTDUInt8 = u8;
144/// A 16-bit signed integer type.
145pub type NSTDInt16 = i16;
146/// A 16-bit unsigned integer type.
147pub type NSTDUInt16 = u16;
148/// A 32-bit signed integer type.
149pub type NSTDInt32 = i32;
150/// A 32-bit unsigned integer type.
151pub type NSTDUInt32 = u32;
152/// A 64-bit signed integer type.
153pub type NSTDInt64 = i64;
154/// A 64-bit unsigned integer type.
155pub type NSTDUInt64 = u64;
156
157/// A 32-bit floating point type.
158pub type NSTDFloat32 = f32;
159/// A 64-bit floating point type.
160pub type NSTDFloat64 = f64;
161
162/// Equivalent to C's `char` type.
163pub type NSTDChar = c_char;
164/// An 8-bit character type.
165pub type NSTDChar8 = NSTDUInt8;
166/// A 16-bit character type.
167pub type NSTDChar16 = NSTDUInt16;
168/// A 32-bit character type.
169pub type NSTDChar32 = NSTDUInt32;
170
171/// A boolean type, can either be `NSTD_TRUE` (1) or `NSTD_FALSE` (0).
172pub type NSTDBool = bool;
173
174/// An opaque pointer to some immutable data.
175pub type NSTDAny = *const c_void;
176/// An opaque pointer to some mutable data.
177pub type NSTDAnyMut = *mut c_void;
178
179/// An FFI-safe reference to some immutable data.
180#[repr(transparent)]
181#[derive(Clone, Copy)]
182pub struct NSTDRef<'a, T>(&'a c_void, PhantomData<&'a T>);
183impl<T> Deref for NSTDRef<'_, T> {
184    /// [`NSTDRef`]'s dereference target.
185    type Target = T;
186
187    /// Gets the immutable reference.
188    #[inline]
189    fn deref(&self) -> &T {
190        let ptr: *const c_void = self.0;
191        // SAFETY: `self.0` is of type `&T`.
192        unsafe { &*(ptr.cast()) }
193    }
194}
195impl<'a, T> From<&'a T> for NSTDRef<'a, T> {
196    /// Creates a new FFI-safe reference.
197    #[inline]
198    fn from(value: &'a T) -> Self {
199        // SAFETY: Reference to reference transmute.
200        Self(unsafe { &*(addr_of!(*value).cast()) }, PhantomData)
201    }
202}
203impl<'a, T> From<&'a mut T> for NSTDRef<'a, T> {
204    /// Creates a new FFI-safe reference.
205    #[inline]
206    fn from(value: &'a mut T) -> Self {
207        // SAFETY: Reference to reference transmute.
208        Self(unsafe { &*(addr_of!(*value).cast()) }, PhantomData)
209    }
210}
211/// An FFI-safe reference to some mutable data.
212#[repr(transparent)]
213pub struct NSTDRefMut<'a, T>(&'a mut c_void, PhantomData<&'a mut T>);
214impl<T> Deref for NSTDRefMut<'_, T> {
215    /// [`NSTDRefMut`]'s dereference target.
216    type Target = T;
217
218    /// Gets the reference.
219    #[inline]
220    fn deref(&self) -> &T {
221        let ptr: *const c_void = self.0;
222        // SAFETY: `self.0` is of type `&mut T`.
223        unsafe { &*(ptr.cast()) }
224    }
225}
226impl<T> DerefMut for NSTDRefMut<'_, T> {
227    /// Gets the mutable reference.
228    #[inline]
229    fn deref_mut(&mut self) -> &mut T {
230        let ptr: *mut c_void = self.0;
231        // SAFETY: `self.0` is of type `&mut T`.
232        unsafe { &mut *(ptr.cast()) }
233    }
234}
235impl<'a, T> From<&'a mut T> for NSTDRefMut<'a, T> {
236    /// Creates a new FFI-safe reference.
237    #[inline]
238    fn from(value: &'a mut T) -> Self {
239        // SAFETY: Reference to reference transmute.
240        Self(unsafe { &mut *addr_of_mut!(*value).cast() }, PhantomData)
241    }
242}
243
244/// An FFI-safe reference to some immutable data, without type safety.
245#[repr(transparent)]
246#[derive(Clone, Copy)]
247pub struct NSTDAnyRef<'a>(&'a c_void);
248impl NSTDAnyRef<'_> {
249    /// Returns a raw pointer to the referenced data.
250    #[inline]
251    const fn as_ptr<T>(&self) -> *const T {
252        let ptr: *const c_void = self.0;
253        ptr.cast()
254    }
255
256    /// Gets the immutable reference.
257    ///
258    /// # Safety
259    ///
260    /// This reference must be pointing to an object of type `T`.
261    #[inline]
262    pub const unsafe fn get<T>(&self) -> &T {
263        &*self.as_ptr()
264    }
265}
266impl<'a, T> From<&'a T> for NSTDAnyRef<'a> {
267    /// Creates a new FFI-safe reference.
268    #[inline]
269    fn from(value: &'a T) -> Self {
270        // SAFETY: Reference to reference transmute.
271        Self(unsafe { &*(addr_of!(*value).cast()) })
272    }
273}
274impl<'a, T> From<&'a mut T> for NSTDAnyRef<'a> {
275    /// Creates a new FFI-safe reference.
276    #[inline]
277    fn from(value: &'a mut T) -> Self {
278        // SAFETY: Reference to reference transmute.
279        Self(unsafe { &*(addr_of!(*value).cast()) })
280    }
281}
282/// An FFI-safe reference to some mutable data, without type safety.
283#[repr(transparent)]
284pub struct NSTDAnyRefMut<'a>(&'a mut c_void);
285impl NSTDAnyRefMut<'_> {
286    /// Returns a raw pointer to the referenced data.
287    #[inline]
288    const fn as_ptr<T>(&self) -> *const T {
289        let ptr: *const c_void = self.0;
290        ptr.cast()
291    }
292
293    /// Returns a mutable raw pointer to the referenced data.
294    #[inline]
295    fn as_mut_ptr<T>(&mut self) -> *mut T {
296        let ptr: *mut c_void = self.0;
297        ptr.cast()
298    }
299
300    /// Gets an immutable reference to the data.
301    ///
302    /// # Safety
303    ///
304    /// This reference must be pointing to an object of type `T`.
305    #[inline]
306    pub const unsafe fn get<T>(&self) -> &T {
307        &*self.as_ptr()
308    }
309
310    /// Gets the mutable reference.
311    ///
312    /// # Safety
313    ///
314    /// This reference must be pointing to an object of type `T`.
315    #[inline]
316    pub unsafe fn get_mut<T>(&mut self) -> &mut T {
317        &mut *self.as_mut_ptr()
318    }
319}
320impl<'a, T> From<&'a mut T> for NSTDAnyRefMut<'a> {
321    /// Creates a new FFI-safe reference.
322    #[inline]
323    fn from(value: &'a mut T) -> Self {
324        // SAFETY: Reference to reference transmute.
325        Self(unsafe { &mut *addr_of_mut!(*value).cast() })
326    }
327}