abi_stable/std_types/
slices.rs

1//! Contains the ffi-safe equivalent of `&'a [T]`.
2
3use std::{
4    borrow::Borrow,
5    io::{self, BufRead, Read},
6    marker::PhantomData,
7    ops::{Deref, Index},
8    slice::SliceIndex,
9};
10
11#[allow(unused_imports)]
12use core_extensions::SelfOps;
13
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15
16use crate::std_types::RVec;
17
18mod private {
19    use super::*;
20
21    /// Ffi-safe equivalent of `&'a [T]`
22    ///
23    /// As of the writing this documentation the abi stability of `&[T]` is
24    /// not yet guaranteed.
25    ///
26    /// # Lifetime problems
27    ///
28    /// Because `RSlice` dereferences into a slice, you can call slice methods on it.
29    ///
30    /// If you call a slice method that returns a borrow into the slice,
31    /// it will have the lifetime of the `let slice: RSlice<'a, [T]>` variable instead of the `'a`
32    /// lifetime that it's parameterized over.
33    ///
34    /// To get a slice with the same lifetime as an `RSlice`,
35    /// one must use the `RSlice::as_slice` method.
36    ///
37    ///
38    /// Example of what would not work:
39    ///
40    /// ```compile_fail
41    /// use abi_stable::std_types::RSlice;
42    ///
43    /// fn into_slice<'a, T>(slic: RSlice<'a, T>) -> &'a [T] {
44    ///     &*slic
45    /// }
46    /// ```
47    ///
48    /// Example of what would work:
49    ///
50    /// ```
51    /// use abi_stable::std_types::RSlice;
52    ///
53    /// fn into_slice<'a, T>(slic: RSlice<'a, T>) -> &'a [T] {
54    ///     slic.as_slice()
55    /// }
56    /// ```
57    ///
58    ///
59    ///
60    /// # Example
61    ///
62    /// Defining an extern fn that returns a reference to
63    /// the first element that compares equal to a parameter.
64    ///
65    /// ```
66    /// use abi_stable::{sabi_extern_fn, std_types::RSlice};
67    ///
68    /// #[sabi_extern_fn]
69    /// pub fn find_first_mut<'a, T>(slice_: RSlice<'a, T>, element: &T) -> Option<&'a T>
70    /// where
71    ///     T: std::cmp::PartialEq,
72    /// {
73    ///     slice_
74    ///         .iter()
75    ///         .position(|x| x == element)
76    ///         .map(|i| &slice_.as_slice()[i])
77    /// }
78    ///
79    /// ```
80    #[repr(C)]
81    #[derive(StableAbi)]
82    #[sabi(bound(T: 'a))]
83    //#[sabi(debug_print)]
84    pub struct RSlice<'a, T> {
85        data: *const T,
86        length: usize,
87        _marker: PhantomData<&'a T>,
88    }
89
90    impl_from_rust_repr! {
91        impl['a, T] From<&'a [T]> for RSlice<'a, T> {
92            fn(this){
93                Self::from_slice(this)
94            }
95        }
96    }
97
98    impl<'a, T: 'a> RSlice<'a, T> {
99        const _EMPTY_SLICE: &'a [T] = &[];
100
101        /// An empty slice.
102        pub const EMPTY: Self = RSlice {
103            data: {
104                let v: &[T] = Self::_EMPTY_SLICE;
105                v.as_ptr()
106            },
107            length: 0,
108            _marker: PhantomData,
109        };
110
111        /// Constructs an `RSlice<'a, T>` from a pointer to the first element,
112        /// and a length.
113        ///
114        /// # Safety
115        ///
116        /// Callers must ensure that:
117        ///
118        /// - `ptr_` points to valid memory,
119        ///
120        /// - `ptr_ .. ptr+len` range is accessible memory.
121        ///
122        /// - `ptr_` is aligned to `T`.
123        ///
124        /// - The data `ptr_` points to must be valid for the `'a` lifetime.
125        ///
126        /// # Examples
127        ///
128        /// This function unsafely converts a `&[T]` to an `RSlice<T>`,
129        /// equivalent to doing `RSlice::from_slice`.
130        ///
131        /// ```
132        /// use abi_stable::std_types::RSlice;
133        ///
134        /// fn convert<T>(slice_: &[T]) -> RSlice<'_, T> {
135        ///     unsafe { RSlice::from_raw_parts(slice_.as_ptr(), slice_.len()) }
136        /// }
137        ///
138        /// ```
139        pub const unsafe fn from_raw_parts(ptr_: *const T, len: usize) -> Self {
140            Self {
141                data: ptr_,
142                length: len,
143                _marker: PhantomData,
144            }
145        }
146
147        #[doc(hidden)]
148        pub const unsafe fn from_raw_parts_with_lifetime(slice: &'a [T], len: usize) -> Self {
149            Self {
150                data: slice.as_ptr(),
151                length: len,
152                _marker: PhantomData,
153            }
154        }
155    }
156
157    impl<'a, T> RSlice<'a, T> {
158        conditionally_const! {
159            feature = "rust_1_64"
160            /// Creates an `&'a [T]` with access to all the elements of this slice.
161            ///
162            ;
163            ///
164            /// # Example
165            ///
166            /// ```
167            /// use abi_stable::std_types::RSlice;
168            ///
169            /// assert_eq!(RSlice::from_slice(&[0, 1, 2, 3]).as_slice(), &[0, 1, 2, 3]);
170            ///
171            /// ```
172            pub fn as_slice(&self) -> &'a [T] {
173                unsafe { ::std::slice::from_raw_parts(self.data, self.length) }
174            }
175        }
176
177        /// Gets a raw pointer to the start of the slice.
178        pub const fn as_ptr(&self) -> *const T {
179            self.data
180        }
181
182        /// The length (in elements) of this slice.
183        ///
184        /// # Example
185        ///
186        /// ```
187        /// use abi_stable::std_types::RSlice;
188        ///
189        /// assert_eq!(RSlice::<u8>::from_slice(&[]).len(), 0);
190        /// assert_eq!(RSlice::from_slice(&[0]).len(), 1);
191        /// assert_eq!(RSlice::from_slice(&[0, 1]).len(), 2);
192        ///
193        /// ```
194        #[inline]
195        pub const fn len(&self) -> usize {
196            self.length
197        }
198
199        /// Whether this slice is empty.
200        ///
201        /// # Example
202        ///
203        /// ```
204        /// use abi_stable::std_types::RSlice;
205        ///
206        /// assert_eq!(RSlice::<u8>::from_slice(&[]).is_empty(), true);
207        /// assert_eq!(RSlice::from_slice(&[0]).is_empty(), false);
208        /// assert_eq!(RSlice::from_slice(&[0, 1]).is_empty(), false);
209        ///
210        /// ```
211        #[inline]
212        pub const fn is_empty(&self) -> bool {
213            self.length == 0
214        }
215    }
216}
217
218pub use self::private::RSlice;
219
220impl<'a, T> RSlice<'a, T> {
221    /// Creates an empty slice
222    pub const fn empty() -> Self {
223        Self::EMPTY
224    }
225
226    /// Converts a reference to `T` to a single element `RSlice<'a, T>`.
227    ///
228    /// Note: this function does not copy anything.
229    ///
230    /// # Example
231    ///
232    /// ```
233    /// use abi_stable::std_types::RSlice;
234    ///
235    /// assert_eq!(RSlice::from_ref(&0), RSlice::from_slice(&[0]));
236    /// assert_eq!(RSlice::from_ref(&1), RSlice::from_slice(&[1]));
237    /// assert_eq!(RSlice::from_ref(&2), RSlice::from_slice(&[2]));
238    ///
239    /// ```
240    pub const fn from_ref(ref_: &'a T) -> Self {
241        unsafe { Self::from_raw_parts(ref_, 1) }
242    }
243
244    /// Converts a `&[T]` to an `RSlice<'_, T>`.
245    ///
246    /// # Example
247    ///
248    /// ```
249    /// use abi_stable::std_types::RSlice;
250    ///
251    /// let empty: &[u8] = &[];
252    ///
253    /// assert_eq!(RSlice::<u8>::from_slice(&[]).as_slice(), empty);
254    /// assert_eq!(RSlice::from_slice(&[0]).as_slice(), &[0][..]);
255    /// assert_eq!(RSlice::from_slice(&[0, 1]).as_slice(), &[0, 1][..]);
256    ///
257    /// ```
258    #[inline]
259    pub const fn from_slice(slic: &'a [T]) -> Self {
260        unsafe { RSlice::from_raw_parts(slic.as_ptr(), slic.len()) }
261    }
262
263    /// Creates an `RSlice<'a, T>` with access to the `range` range of elements.
264    ///
265    /// This is an inherent method instead of an implementation of the
266    /// `std::ops::Index` trait because it does not return a reference.
267    ///
268    /// # Example
269    ///
270    /// ```
271    /// use abi_stable::std_types::RSlice;
272    ///
273    /// let slic = RSlice::from_slice(&[0, 1, 2, 3]);
274    ///
275    /// assert_eq!(slic.slice(..), RSlice::from_slice(&[0, 1, 2, 3]));
276    /// assert_eq!(slic.slice(..2), RSlice::from_slice(&[0, 1]));
277    /// assert_eq!(slic.slice(2..), RSlice::from_slice(&[2, 3]));
278    /// assert_eq!(slic.slice(1..3), RSlice::from_slice(&[1, 2]));
279    ///
280    /// ```
281    pub fn slice<I>(&self, i: I) -> RSlice<'a, T>
282    where
283        [T]: Index<I, Output = [T]>,
284    {
285        self.as_slice().index(i).into()
286    }
287
288    /// Creates a new `RVec<T>` and clones all the elements of this slice into it.
289    ///
290    /// # Example
291    ///
292    /// ```
293    /// use abi_stable::std_types::{RSlice, RVec};
294    ///
295    /// let slic = RSlice::from_slice(&[0, 1, 2, 3]);
296    ///
297    /// assert_eq!(slic.slice(..).to_rvec(), RVec::from_slice(&[0, 1, 2, 3]));
298    /// assert_eq!(slic.slice(..2).to_rvec(), RVec::from_slice(&[0, 1]));
299    /// assert_eq!(slic.slice(2..).to_rvec(), RVec::from_slice(&[2, 3]));
300    /// assert_eq!(slic.slice(1..3).to_rvec(), RVec::from_slice(&[1, 2]));
301    ///
302    /// ```
303    pub fn to_rvec(&self) -> RVec<T>
304    where
305        T: Clone,
306    {
307        self.to_vec().into()
308    }
309
310    /// Transmutes n `RSlice<'a, T>` to a `RSlice<'a, U>`
311    ///
312    /// # Safety
313    ///
314    /// This has the same safety requirements as calling [`std::mem::transmute`] to
315    /// transmute a `&'a [T]` to a `&'a [U]`.
316    ///
317    /// [`std::mem::transmute`]: https://doc.rust-lang.org/std/mem/fn.transmute.html
318    pub const unsafe fn transmute<U>(self) -> RSlice<'a, U>
319    where
320        U: 'a,
321    {
322        let len = self.len();
323        unsafe { RSlice::from_raw_parts(self.as_ptr() as *const T as *const U, len) }
324    }
325}
326
327unsafe impl<'a, T> Send for RSlice<'a, T> where &'a [T]: Send {}
328unsafe impl<'a, T> Sync for RSlice<'a, T> where &'a [T]: Sync {}
329
330impl<'a, T> Copy for RSlice<'a, T> {}
331
332impl<'a, T> Clone for RSlice<'a, T> {
333    fn clone(&self) -> Self {
334        *self
335    }
336}
337
338impl<'a, T> Default for RSlice<'a, T> {
339    fn default() -> Self {
340        (&[][..]).into()
341    }
342}
343
344impl<'a, T> IntoIterator for RSlice<'a, T> {
345    type Item = &'a T;
346
347    type IntoIter = ::std::slice::Iter<'a, T>;
348
349    fn into_iter(self) -> ::std::slice::Iter<'a, T> {
350        self.as_slice().iter()
351    }
352}
353
354impl<'a, T, I: SliceIndex<[T]>> Index<I> for RSlice<'a, T> {
355    type Output = I::Output;
356
357    #[inline]
358    fn index(&self, index: I) -> &Self::Output {
359        self.get(index).expect("Index out of bounds")
360    }
361}
362
363slice_like_impl_cmp_traits! {
364    impl[] RSlice<'_, T>,
365    where[];
366    Vec<U>,
367    [U],
368    &[U],
369}
370
371slice_like_impl_cmp_traits! {
372    impl[const N: usize] RSlice<'_, T>,
373    where[];
374    [U; N],
375}
376
377slice_like_impl_cmp_traits! {
378    impl[] RSlice<'_, T>,
379    where[T: Clone, U: Clone];
380    std::borrow::Cow<'_, [U]>,
381    crate::std_types::RCowSlice<'_, U>,
382}
383
384impl<'a, T: 'a> Deref for RSlice<'a, T> {
385    type Target = [T];
386
387    fn deref(&self) -> &Self::Target {
388        self.as_slice()
389    }
390}
391
392impl_into_rust_repr! {
393    impl['a, T] Into<&'a [T]> for RSlice<'a, T> {
394        fn(this){
395            this.as_slice()
396        }
397    }
398}
399
400////////////////////
401
402impl<'a, T: 'a> Borrow<[T]> for RSlice<'a, T> {
403    fn borrow(&self) -> &[T] {
404        self
405    }
406}
407
408impl<'a, T: 'a> AsRef<[T]> for RSlice<'a, T> {
409    fn as_ref(&self) -> &[T] {
410        self
411    }
412}
413
414///////////////////
415
416impl<'de, T> Deserialize<'de> for RSlice<'de, T>
417where
418    &'de [T]: Deserialize<'de>,
419{
420    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
421    where
422        D: Deserializer<'de>,
423    {
424        <&'de [T] as Deserialize<'de>>::deserialize(deserializer).map(Self::from)
425    }
426}
427
428impl<'a, T> Serialize for RSlice<'a, T>
429where
430    T: Serialize,
431{
432    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
433    where
434        S: Serializer,
435    {
436        self.as_slice().serialize(serializer)
437    }
438}
439
440///////////////////////////////////////////////////////////////////////////////
441
442impl<'a> Read for RSlice<'a, u8> {
443    #[inline]
444    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
445        let mut this = self.as_slice();
446        let ret = this.read(buf);
447        *self = this.into();
448        ret
449    }
450
451    #[inline]
452    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
453        let mut this = self.as_slice();
454        let ret = this.read_exact(buf);
455        *self = this.into();
456        ret
457    }
458
459    #[inline]
460    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
461        let mut this = self.as_slice();
462        let ret = this.read_to_end(buf);
463        *self = this.into();
464        ret
465    }
466}
467
468impl<'a> BufRead for RSlice<'a, u8> {
469    #[inline]
470    fn fill_buf(&mut self) -> io::Result<&[u8]> {
471        Ok(&**self)
472    }
473
474    #[inline]
475    fn consume(&mut self, amt: usize) {
476        *self = self.slice(amt..);
477    }
478}
479
480///////////////////////////////////////////////////////////////////////////////
481
482#[allow(dead_code)]
483type Slice<'a, T> = &'a [T];
484
485shared_impls! {
486    mod = slice_impls
487    new_type = RSlice['a][T],
488    original_type = Slice,
489}
490
491////////////////////////////////////////////////////////////////////////////////
492
493//#[cfg(test)]
494#[cfg(all(test, not(feature = "only_new_tests")))]
495mod test {
496    use super::*;
497
498    #[test]
499    fn from_to_slice() {
500        let a = "what the hell".as_bytes();
501        let b = RSlice::from(a);
502
503        assert_eq!(a, &*b);
504        assert_eq!(a.len(), b.len());
505    }
506
507    #[cfg(feature = "rust_1_64")]
508    #[test]
509    fn const_as_slice_test() {
510        const RS: RSlice<'_, u8> = RSlice::from_slice(&[3, 5, 8]);
511        const SLICE: &[u8] = RS.as_slice();
512
513        assert_eq!(SLICE, [3, 5, 8]);
514    }
515
516    #[test]
517    fn test_index() {
518        let s = rslice![1, 2, 3, 4, 5];
519
520        assert_eq!(s.index(0), &1);
521        assert_eq!(s.index(4), &5);
522        assert_eq!(s.index(..2), rslice![1, 2]);
523        assert_eq!(s.index(1..2), rslice![2]);
524        assert_eq!(s.index(3..), rslice![4, 5]);
525    }
526}