stabby_abi/
slice.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   Pierre Avital, <pierre.avital@me.com>
13//
14
15//! Stable slices!
16
17use crate as stabby;
18use core::ops::{Deref, DerefMut};
19
20/// An ABI stable equivalent of `&'a [T]`
21#[stabby::stabby]
22pub struct Slice<'a, T: 'a> {
23    /// The start of the slice.
24    pub start: core::ptr::NonNull<T>,
25    /// The length of the slice.
26    pub len: usize,
27    /// Ensures the slice has correct lifetime and variance.
28    pub marker: core::marker::PhantomData<&'a ()>,
29}
30// SAFETY: Slices are analogous to references.
31unsafe impl<'a, T: 'a> Send for Slice<'a, T> where &'a T: Send {}
32// SAFETY: Slices are analogous to references.
33unsafe impl<'a, T: 'a> Sync for Slice<'a, T> where &'a T: Sync {}
34impl<'a, T: 'a> Clone for Slice<'a, T> {
35    fn clone(&self) -> Self {
36        *self
37    }
38}
39impl<'a, T: 'a> Copy for Slice<'a, T> {}
40
41impl<'a, T: 'a> Slice<'a, T> {
42    /// Convert `&[T]` to its ABI-stable equivalent.
43    pub const fn new(value: &'a [T]) -> Self {
44        Self {
45            start: unsafe { core::ptr::NonNull::new_unchecked(value.as_ptr() as *mut T) },
46            len: value.len(),
47            marker: core::marker::PhantomData,
48        }
49    }
50    /// Obtain `&[T]` from its ABI-stable equivalent.
51    pub const fn as_slice(self) -> &'a [T] {
52        unsafe { core::slice::from_raw_parts(self.start.as_ptr(), self.len) }
53    }
54}
55impl<'a, T> From<&'a [T]> for Slice<'a, T> {
56    fn from(value: &'a [T]) -> Self {
57        Self::new(value)
58    }
59}
60impl<'a, T> From<&'a mut [T]> for Slice<'a, T> {
61    fn from(value: &'a mut [T]) -> Self {
62        Self {
63            start: unsafe { core::ptr::NonNull::new_unchecked(value.as_ptr() as *mut T) },
64            len: value.len(),
65            marker: core::marker::PhantomData,
66        }
67    }
68}
69
70impl<'a, T> From<Slice<'a, T>> for &'a [T] {
71    fn from(value: Slice<'a, T>) -> Self {
72        unsafe { core::slice::from_raw_parts(value.start.as_ptr(), value.len) }
73    }
74}
75impl<T> Deref for Slice<'_, T> {
76    type Target = [T];
77    fn deref(&self) -> &Self::Target {
78        unsafe { core::slice::from_raw_parts(self.start.as_ptr(), self.len) }
79    }
80}
81impl<'a, T: 'a> Eq for Slice<'a, T> where for<'b> &'b [T]: Eq {}
82impl<'a, T: 'a> PartialEq for Slice<'a, T>
83where
84    for<'b> &'b [T]: PartialEq,
85{
86    fn eq(&self, other: &Self) -> bool {
87        self.deref() == other.deref()
88    }
89}
90impl<'a, T: 'a> core::fmt::Debug for Slice<'a, T>
91where
92    for<'b> &'b [T]: core::fmt::Debug,
93{
94    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95        self.deref().fmt(f)
96    }
97}
98impl<'a, T: 'a> core::fmt::Display for Slice<'a, T>
99where
100    for<'b> &'b [T]: core::fmt::Display,
101{
102    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103        self.deref().fmt(f)
104    }
105}
106impl<'a, T: 'a> core::hash::Hash for Slice<'a, T>
107where
108    for<'b> &'b [T]: core::hash::Hash,
109{
110    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
111        self.deref().hash(state);
112    }
113}
114
115/// An ABI stable equivalent of `&'a mut T`
116#[stabby::stabby]
117pub struct SliceMut<'a, T: 'a> {
118    /// The start of the slice.
119    pub start: core::ptr::NonNull<T>,
120    /// The length of the slice.
121    pub len: usize,
122    /// Ensures the slice has correct lifetime and variance.
123    pub marker: core::marker::PhantomData<&'a mut ()>,
124}
125// SAFETY: SliceMut is analogous to a mutable reference
126unsafe impl<'a, T: 'a> Send for SliceMut<'a, T> where &'a mut T: Send {}
127// SAFETY: SliceMut is analogous to a mutable reference
128unsafe impl<'a, T: 'a> Sync for SliceMut<'a, T> where &'a mut T: Sync {}
129impl<T> Deref for SliceMut<'_, T> {
130    type Target = [T];
131    fn deref(&self) -> &Self::Target {
132        unsafe { core::slice::from_raw_parts(self.start.as_ref(), self.len) }
133    }
134}
135impl<T> DerefMut for SliceMut<'_, T> {
136    fn deref_mut(&mut self) -> &mut Self::Target {
137        unsafe { core::slice::from_raw_parts_mut(self.start.as_mut(), self.len) }
138    }
139}
140impl<'a, T: 'a> Eq for SliceMut<'a, T> where for<'b> &'b [T]: Eq {}
141impl<'a, T: 'a> PartialEq for SliceMut<'a, T>
142where
143    for<'b> &'b [T]: PartialEq,
144{
145    fn eq(&self, other: &Self) -> bool {
146        self.deref() == other.deref()
147    }
148}
149impl<'a, T: 'a> core::fmt::Debug for SliceMut<'a, T>
150where
151    for<'b> &'b [T]: core::fmt::Debug,
152{
153    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
154        self.deref().fmt(f)
155    }
156}
157impl<'a, T: 'a> core::fmt::Display for SliceMut<'a, T>
158where
159    for<'b> &'b [T]: core::fmt::Display,
160{
161    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162        self.deref().fmt(f)
163    }
164}
165impl<'a, T: 'a> core::hash::Hash for SliceMut<'a, T>
166where
167    for<'b> &'b [T]: core::hash::Hash,
168{
169    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
170        self.deref().hash(state);
171    }
172}
173impl<'a, T> From<&'a mut [T]> for SliceMut<'a, T> {
174    fn from(value: &'a mut [T]) -> Self {
175        Self {
176            start: unsafe { core::ptr::NonNull::new_unchecked(value.as_mut_ptr()) },
177            len: value.len(),
178            marker: core::marker::PhantomData,
179        }
180    }
181}
182impl<'a, T> From<SliceMut<'a, T>> for Slice<'a, T> {
183    fn from(value: SliceMut<'a, T>) -> Self {
184        Self {
185            start: value.start,
186            len: value.len,
187            marker: core::marker::PhantomData,
188        }
189    }
190}
191impl<'a, T> From<SliceMut<'a, T>> for &'a mut [T] {
192    fn from(mut value: SliceMut<'a, T>) -> Self {
193        unsafe { core::slice::from_raw_parts_mut(value.start.as_mut(), value.len) }
194    }
195}
196
197impl<'a, T> From<SliceMut<'a, T>> for &'a [T] {
198    fn from(mut value: SliceMut<'a, T>) -> Self {
199        unsafe { core::slice::from_raw_parts(value.start.as_mut(), value.len) }
200    }
201}
202
203#[cfg(feature = "serde")]
204mod serde_impl {
205    use super::*;
206    use serde::{de::Visitor, Deserialize, Serialize};
207    impl<T: Serialize> Serialize for Slice<'_, T> {
208        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
209        where
210            S: serde::Serializer,
211        {
212            let slice: &[T] = self;
213            slice.serialize(serializer)
214        }
215    }
216    impl<T: Serialize> Serialize for SliceMut<'_, T> {
217        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
218        where
219            S: serde::Serializer,
220        {
221            let slice: &[T] = self;
222            slice.serialize(serializer)
223        }
224    }
225    impl<'a> Deserialize<'a> for Slice<'a, u8> {
226        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
227        where
228            D: serde::Deserializer<'a>,
229        {
230            deserializer.deserialize_bytes(BytesVisitor(core::marker::PhantomData))
231        }
232    }
233    struct BytesVisitor<'a>(core::marker::PhantomData<Slice<'a, u8>>);
234    impl<'a> Visitor<'a> for BytesVisitor<'a> {
235        type Value = Slice<'a, u8>;
236        fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
237        where
238            E: serde::de::Error,
239        {
240            Ok(v.into())
241        }
242        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
243            write!(formatter, "A borrowed_str")
244        }
245    }
246}