aligned_ptr/
slice.rs

1//! A module containing functions defined in [`core::slice`] with null and alignment checks.
2
3use crate::return_error_on_null_or_misaligned;
4use crate::Result;
5use crate::ERR_MSG;
6
7/// The wrapper of [`core::slice::from_raw_parts_mut`] which panics if the passed pointer is either
8/// null or not aligned.
9///
10/// # Safety
11///
12/// The caller must follow the rules required by [`core::slice::from_raw_parts_mut`] except the
13/// alignment and null rules.
14///
15/// # Examples
16///
17/// ```rust
18/// use aligned_ptr::slice;
19///
20/// let mut x = 3;
21/// let s = unsafe { slice::from_raw_parts_mut(&mut x, 1) };
22///
23/// assert_eq!(s, [3]);
24/// ```
25pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
26    // SAFETY: The caller must uphold the all safety rules.
27    let r = unsafe { try_from_raw_parts_mut(data, len) };
28    r.expect(ERR_MSG)
29}
30
31/// The wrapper of [`core::slice::from_raw_parts_mut`] which may return an error if the passed
32/// pointer is either null or not aligned.
33///
34/// # Safety
35///
36/// The caller must follow the rules required by [`core::slice::from_raw_parts_mut`] except the
37/// alignment and null rules.
38///
39/// # Errors
40///
41/// This function may return an error:
42///
43/// - [`crate::Error::Null`] - `p` is null.
44/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
45///
46/// # Examples
47///
48/// ```rust
49/// use aligned_ptr::slice;
50/// use aligned_ptr::Error;
51///
52/// let mut x = 3;
53/// let s = unsafe { slice::try_from_raw_parts_mut(&mut x, 1) };
54///
55/// assert!(s.is_ok());
56/// assert_eq!(s.unwrap(), [3]);
57///
58/// let p: *mut i32 = core::ptr::null_mut();
59/// let s = unsafe { slice::try_from_raw_parts_mut(p, 1) };
60/// assert_eq!(s, Err(Error::Null));
61///
62/// let p = 0x1001 as *mut i32;
63/// let s = unsafe { slice::try_from_raw_parts_mut(p, 1) };
64/// assert_eq!(s, Err(Error::NotAligned));
65/// ```
66pub unsafe fn try_from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> Result<&'a mut [T]> {
67    return_error_on_null_or_misaligned(data)?;
68
69    // SAFETY: The caller must uphold the all safety rules.
70    Ok(unsafe { core::slice::from_raw_parts_mut(data, len) })
71}
72
73/// The wrapper of [`core::slice::from_raw_parts`] which panics if the passed pointer is either
74/// null or not aligned.
75///
76/// # Safety
77///
78/// The caller must follow the safety requirements of [`core::slice::from_raw_parts`] except the
79/// alignment and null requirements.
80///
81/// # Examples
82///
83/// ```rust
84/// use aligned_ptr::slice;
85/// use aligned_ptr::Error;
86///
87/// let x = 3;
88/// let s = unsafe { slice::from_raw_parts(&x, 1) };
89///
90/// assert_eq!(s, [3]);
91/// ```
92pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
93    // SAFETY: The caller must uphold the safety requirements.
94    unsafe { try_from_raw_parts(data, len).expect(ERR_MSG) }
95}
96
97/// The wrapper of [`core::slice::from_raw_parts`] which may return an error if the passed pointer
98/// is either null or not aligned.
99///
100/// # Safety
101///
102/// The caller must follow the safety rules required by [`core::slice::from_raw_parts`] except the
103/// alignment and null requirements.
104///
105/// # Errors
106///
107/// This function may return an error:
108///
109/// - [`crate::Error::Null`] - `data` is null.
110/// - [`crate::Error::NotAligned`] - `data` is not aligned correctly.
111///
112/// # Examples
113///
114/// ```rust
115/// use aligned_ptr::slice;
116/// use aligned_ptr::Error;
117///
118/// let x = 3;
119/// let s = unsafe { slice::try_from_raw_parts(&x, 1) };
120///
121/// assert!(s.is_ok());
122/// assert_eq!(s.unwrap(), [3]);
123///
124/// let p: *const i32 = core::ptr::null();
125/// let s = unsafe { slice::try_from_raw_parts(p, 1) };
126/// assert_eq!(s, Err(Error::Null));
127///
128/// let p = 0x1001 as *const i32;
129/// let s = unsafe { slice::try_from_raw_parts(p, 1) };
130/// assert_eq!(s, Err(Error::NotAligned));
131/// ```
132pub unsafe fn try_from_raw_parts<'a, T>(data: *const T, len: usize) -> Result<&'a [T]> {
133    return_error_on_null_or_misaligned(data)?;
134
135    // SAFETY: The caller must uphold the safety requirements.
136    Ok(unsafe { core::slice::from_raw_parts(data, len) })
137}