abi_stable/std_types/
slice_mut.rs

1//! Contains the ffi-safe equivalent of `&'a mut [T]`.
2
3use std::{
4    borrow::{Borrow, BorrowMut},
5    io::{self, Write},
6    marker::PhantomData,
7    mem,
8    ops::{Deref, DerefMut, Index, IndexMut},
9    slice::SliceIndex,
10};
11
12use serde::{Serialize, Serializer};
13
14#[allow(unused_imports)]
15use core_extensions::SelfOps;
16
17use crate::std_types::{RSlice, RVec};
18
19mod privacy {
20    use super::*;
21
22    /// Ffi-safe equivalent of `&'a mut [T]`
23    ///
24    /// As of the writing this documentation the abi stability of `&mut [T]` is
25    /// not yet guaranteed.
26    ///
27    /// # Lifetime problems
28    ///
29    /// Because `RSliceMut` dereferences into a mutable slice, you can call slice methods on it.
30    ///
31    /// If you call a slice method that returns a borrow into the slice,
32    /// it will have the lifetime of the `let slice: RSliceMut<'a, [T]>` variable instead of the `'a`
33    /// lifetime that it's parameterized over.
34    ///
35    /// To get a slice with the same lifetime as an `RSliceMut`,
36    /// one must use one of the `RSliceMut::{into_slice, into_mut_slice}` methods.
37    ///
38    ///
39    /// Example of what would not work:
40    ///
41    /// ```compile_fail
42    /// use abi_stable::std_types::RSliceMut;
43    ///
44    /// fn into_slice<'a, T>(slic: RSliceMut<'a, T>) -> &'a [T] {
45    ///     &*slic
46    /// }
47    ///
48    /// fn into_mut_slice<'a, T>(slic: RSliceMut<'a, T>) -> &'a mut [T] {
49    ///     &mut *slic
50    /// }
51    /// ```
52    ///
53    /// Example of what would work:
54    ///
55    /// ```
56    /// use abi_stable::std_types::RSliceMut;
57    ///
58    /// fn into_slice<'a, T>(slic: RSliceMut<'a, T>) -> &'a [T] {
59    ///     slic.into_slice()
60    /// }
61    ///
62    /// fn into_mut_slice<'a, T>(slic: RSliceMut<'a, T>) -> &'a mut [T] {
63    ///     slic.into_mut_slice()
64    /// }
65    ///
66    /// ```
67    ///
68    ///
69    /// # Example
70    ///
71    /// Defining an extern fn that returns a mutable reference to
72    /// the first element that compares equal to a parameter.
73    ///
74    /// ```
75    /// use abi_stable::{sabi_extern_fn, std_types::RSliceMut};
76    ///
77    /// #[sabi_extern_fn]
78    /// pub fn find_first_mut<'a, T>(
79    ///     slice_: RSliceMut<'a, T>,
80    ///     element: &T,
81    /// ) -> Option<&'a mut T>
82    /// where
83    ///     T: std::cmp::PartialEq,
84    /// {
85    ///     slice_
86    ///         .iter()
87    ///         .position(|x| x == element)
88    ///         .map(|i| &mut slice_.into_mut_slice()[i])
89    /// }
90    /// ```
91    ///
92    #[repr(C)]
93    #[derive(StableAbi)]
94    #[sabi(bound(T: 'a))]
95    pub struct RSliceMut<'a, T> {
96        data: *mut T,
97        length: usize,
98        _marker: PhantomData<MutWorkaround<'a, T>>,
99    }
100
101    /// Used as a workaround to make `from_raw_parts_mut` a const fn.
102    #[repr(C)]
103    #[derive(StableAbi)]
104    #[sabi(bound(T: 'a))]
105    struct MutWorkaround<'a, T>(&'a mut T);
106
107    impl_from_rust_repr! {
108        impl['a, T] From<&'a mut [T]> for RSliceMut<'a, T> {
109            fn(this){
110                RSliceMut {
111                    data: this.as_mut_ptr(),
112                    length: this.len(),
113                    _marker: Default::default(),
114                }
115            }
116        }
117    }
118
119    impl<'a, T> RSliceMut<'a, T> {
120        #[inline(always)]
121        pub(super) const fn data(&self) -> *mut T {
122            self.data
123        }
124
125        /// Gets a raw pointer to the start of the slice.
126        pub const fn as_ptr(&self) -> *const T {
127            self.data
128        }
129
130        /// Gets a mutable raw pointer to the start of the slice.
131        pub fn as_mut_ptr(&mut self) -> *mut T {
132            self.data
133        }
134
135        /// Gets a mutable raw pointer to the start of the slice.
136        pub const fn into_mut_ptr(self) -> *mut T {
137            self.data
138        }
139
140        /// The length (in elements) of this slice.
141        ///
142        /// # Example
143        ///
144        /// ```
145        /// use abi_stable::std_types::RSliceMut;
146        ///
147        /// assert_eq!(RSliceMut::<u8>::from_mut_slice(&mut []).len(), 0);
148        /// assert_eq!(RSliceMut::from_mut_slice(&mut [0]).len(), 1);
149        /// assert_eq!(RSliceMut::from_mut_slice(&mut [0, 1]).len(), 2);
150        ///
151        /// ```
152        #[inline(always)]
153        pub const fn len(&self) -> usize {
154            self.length
155        }
156
157        /// Whether this slice is empty.
158        ///
159        /// # Example
160        ///
161        /// ```
162        /// use abi_stable::std_types::RSliceMut;
163        ///
164        /// assert_eq!(RSliceMut::<u8>::from_mut_slice(&mut []).is_empty(), true);
165        /// assert_eq!(RSliceMut::from_mut_slice(&mut [0]).is_empty(), false);
166        /// assert_eq!(RSliceMut::from_mut_slice(&mut [0, 1]).is_empty(), false);
167        ///
168        /// ```
169        #[inline]
170        pub const fn is_empty(&self) -> bool {
171            self.length == 0
172        }
173
174        /// Constructs an `RSliceMut<'a, T>` from a pointer to the first element,
175        /// and a length.
176        ///
177        /// # Safety
178        ///
179        /// Callers must ensure that:
180        ///
181        /// - `ptr_` points to valid memory,
182        ///
183        /// - `ptr_ .. ptr+len` range is accessible memory.
184        ///
185        /// - `ptr_` is aligned to `T`.
186        ///
187        /// - the data `ptr_` points to must be valid for the lifetime of this `RSlice<'a, T>`
188        ///
189        /// # Examples
190        ///
191        /// This function unsafely converts a `&mut [T]` to an `RSliceMut<T>`,
192        /// equivalent to doing `RSliceMut::from_mut_slice`.
193        ///
194        /// ```
195        /// use abi_stable::std_types::RSliceMut;
196        ///
197        /// fn convert<T>(slice_: &mut [T]) -> RSliceMut<'_, T> {
198        ///     let len = slice_.len();
199        ///     unsafe { RSliceMut::from_raw_parts_mut(slice_.as_mut_ptr(), len) }
200        /// }
201        ///
202        /// ```
203        pub const unsafe fn from_raw_parts_mut(ptr_: *mut T, len: usize) -> Self {
204            Self {
205                data: ptr_,
206                length: len,
207                // WHAT!?
208                // error[E0723]: mutable references in const fn are unstable (see issue #57563)
209                _marker: PhantomData,
210            }
211        }
212    }
213}
214pub use self::privacy::RSliceMut;
215
216impl<'a, T> RSliceMut<'a, T> {
217    // pub const fn empty() -> Self {
218    //     Self::EMPTY
219    // }
220
221    /// Converts a mutable reference to `T` to a single element `RSliceMut<'a, T>`.
222    ///
223    /// Note: this function does not copy anything.
224    ///
225    /// # Example
226    ///
227    /// ```
228    /// use abi_stable::std_types::RSliceMut;
229    ///
230    /// assert_eq!(
231    ///     RSliceMut::from_mut(&mut 0),
232    ///     RSliceMut::from_mut_slice(&mut [0])
233    /// );
234    /// assert_eq!(
235    ///     RSliceMut::from_mut(&mut 1),
236    ///     RSliceMut::from_mut_slice(&mut [1])
237    /// );
238    /// assert_eq!(
239    ///     RSliceMut::from_mut(&mut 2),
240    ///     RSliceMut::from_mut_slice(&mut [2])
241    /// );
242    ///
243    /// ```
244    pub fn from_mut(ref_: &'a mut T) -> Self {
245        unsafe { Self::from_raw_parts_mut(ref_, 1) }
246    }
247
248    /// Converts a `&'a mut [T]` to a `RSliceMut<'a, T>`.
249    ///
250    /// # Example
251    ///
252    /// ```
253    /// use abi_stable::std_types::RSliceMut;
254    ///
255    /// let empty: &mut [u8] = &mut [];
256    ///
257    /// assert_eq!(
258    ///     RSliceMut::<u8>::from_mut_slice(&mut []).as_mut_slice(),
259    ///     empty
260    /// );
261    /// assert_eq!(
262    ///     RSliceMut::from_mut_slice(&mut [0]).as_mut_slice(),
263    ///     &mut [0][..]
264    /// );
265    /// assert_eq!(
266    ///     RSliceMut::from_mut_slice(&mut [0, 1]).as_mut_slice(),
267    ///     &mut [0, 1][..]
268    /// );
269    ///
270    /// ```
271    #[inline]
272    pub fn from_mut_slice(slic: &'a mut [T]) -> Self {
273        slic.into()
274    }
275
276    /// Creates an `RSlice<'b, T>` with access to the `range` range of elements.
277    ///
278    /// This is an inherent method instead of an implementation of the
279    /// `std::ops::Index` trait because it does not return a reference.
280    ///
281    /// # Example
282    ///
283    /// ```
284    /// use abi_stable::std_types::{RSlice, RSliceMut};
285    ///
286    /// let slic = &mut [0, 1, 2, 3];
287    /// let slic = RSliceMut::from_mut_slice(slic);
288    ///
289    /// assert_eq!(slic.slice(..), RSlice::from_slice(&[0, 1, 2, 3]));
290    /// assert_eq!(slic.slice(..2), RSlice::from_slice(&[0, 1]));
291    /// assert_eq!(slic.slice(2..), RSlice::from_slice(&[2, 3]));
292    /// assert_eq!(slic.slice(1..3), RSlice::from_slice(&[1, 2]));
293    ///
294    /// ```
295    #[allow(clippy::needless_lifetimes)]
296    pub fn slice<'b, I>(&'b self, i: I) -> RSlice<'b, T>
297    where
298        [T]: Index<I, Output = [T]>,
299    {
300        self.as_slice().index(i).into()
301    }
302
303    /// Creates an `RSliceMut<'a, T>` with access to the `range` range of elements.
304    ///
305    /// This is an inherent method instead of an implementation of the
306    /// `std::ops::IndexMut` trait because it does not return a reference.
307    ///
308    /// # Example
309    ///
310    /// ```
311    /// use abi_stable::std_types::RSliceMut;
312    ///
313    /// let slic = &mut [0, 1, 2, 3];
314    /// let mut slic = RSliceMut::from_mut_slice(slic);
315    ///
316    /// assert_eq!(
317    ///     slic.slice_mut(..),
318    ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3])
319    /// );
320    /// assert_eq!(slic.slice_mut(..2), RSliceMut::from_mut_slice(&mut [0, 1]));
321    /// assert_eq!(slic.slice_mut(2..), RSliceMut::from_mut_slice(&mut [2, 3]));
322    /// assert_eq!(slic.slice_mut(1..3), RSliceMut::from_mut_slice(&mut [1, 2]));
323    ///
324    /// ```
325    #[allow(clippy::needless_lifetimes)]
326    pub fn slice_mut<'b, I>(&'b mut self, i: I) -> RSliceMut<'b, T>
327    where
328        [T]: IndexMut<I, Output = [T]>,
329    {
330        self.as_mut_slice().index_mut(i).into()
331    }
332
333    /// Creates a new `RVec<T>` and clones all the elements of this slice into it.
334    ///
335    /// # Example
336    ///
337    /// ```
338    /// use abi_stable::std_types::{RSliceMut, RVec};
339    ///
340    /// let slic = &mut [0, 1, 2, 3];
341    /// let slic = RSliceMut::from_mut_slice(slic);
342    ///
343    /// assert_eq!(slic.slice(..).to_rvec(), RVec::from_slice(&[0, 1, 2, 3]));
344    /// assert_eq!(slic.slice(..2).to_rvec(), RVec::from_slice(&[0, 1]));
345    /// assert_eq!(slic.slice(2..).to_rvec(), RVec::from_slice(&[2, 3]));
346    /// assert_eq!(slic.slice(1..3).to_rvec(), RVec::from_slice(&[1, 2]));
347    ///
348    /// ```
349    pub fn to_rvec(&self) -> RVec<T>
350    where
351        T: Clone,
352    {
353        self.to_vec().into()
354    }
355
356    conditionally_const! {
357        feature = "rust_1_64"
358        ;
359        unsafe fn as_slice_unbounded_lifetime(&self) -> &'a [T] {
360            unsafe { ::std::slice::from_raw_parts(self.data(), self.len()) }
361        }
362    }
363
364    unsafe fn as_mut_slice_unbounded_lifetime(&mut self) -> &'a mut [T] {
365        unsafe { ::std::slice::from_raw_parts_mut(self.data(), self.len()) }
366    }
367
368    conditionally_const! {
369        feature = "rust_1_64"
370        /// Creates an `&'_ [T]` with access to all the elements of this slice.
371        ///
372        ;
373        ///
374        /// # Example
375        ///
376        /// ```
377        /// use abi_stable::std_types::RSliceMut;
378        ///
379        /// assert_eq!(
380        ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3]).as_slice(),
381        ///     &[0, 1, 2, 3]
382        /// );
383        ///
384        /// ```
385        pub fn as_slice(&self) -> &[T] {
386            unsafe { self.as_slice_unbounded_lifetime() }
387        }
388    }
389
390    conditionally_const! {
391        feature = "rust_1_64"
392        /// Creates an `&'a [T]` with access to all the elements of this slice.
393        ///
394        /// This is different to `as_slice` in that the returned lifetime of
395        /// this function  is larger.
396        ///
397        ;
398        ///
399        /// # Example
400        ///
401        /// ```
402        /// use abi_stable::std_types::RSliceMut;
403        ///
404        /// assert_eq!(
405        ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3]).into_slice(),
406        ///     &[0, 1, 2, 3]
407        /// );
408        ///
409        /// ```
410        pub fn into_slice(self) -> &'a [T] {
411            unsafe { self.as_slice_unbounded_lifetime() }
412        }
413    }
414
415    /// Creates an `RSlice<'_, T>` with access to all the elements of this slice.
416    ///
417    /// # Example
418    ///
419    /// ```
420    /// use abi_stable::std_types::{RSlice, RSliceMut};
421    ///
422    /// assert_eq!(
423    ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3]).as_rslice(),
424    ///     RSlice::from_slice(&[0, 1, 2, 3]),
425    /// );
426    ///
427    /// ```
428    pub fn as_rslice(&self) -> RSlice<'_, T> {
429        self.as_slice().into()
430    }
431
432    /// Creates an `RSlice<'a, T>` with access to all the elements of this slice.
433    ///
434    /// This is different to `as_rslice` in that the returned lifetime of
435    /// this function  is larger.
436    ///
437    /// # Example
438    ///
439    /// ```
440    /// use abi_stable::std_types::{RSlice, RSliceMut};
441    ///
442    /// assert_eq!(
443    ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3]).into_rslice(),
444    ///     RSlice::from_slice(&[0, 1, 2, 3]),
445    /// );
446    ///
447    /// ```
448    pub fn into_rslice(self) -> RSlice<'a, T> {
449        self.into_slice().into()
450    }
451
452    /// Creates a `&'_ mut [T]` with access to all the elements of this slice.
453    ///
454    /// # Example
455    ///
456    /// ```
457    /// use abi_stable::std_types::RSliceMut;
458    ///
459    /// assert_eq!(
460    ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3]).as_mut_slice(),
461    ///     &mut [0, 1, 2, 3]
462    /// );
463    ///
464    /// ```
465    pub fn as_mut_slice(&mut self) -> &mut [T] {
466        unsafe { self.as_mut_slice_unbounded_lifetime() }
467    }
468
469    /// Creates a `&'a mut [T]` with access to all the elements of this slice.
470    ///
471    /// This is different to `as_mut_slice` in that the returned lifetime of
472    /// this function is larger.
473    ///
474    /// # Example
475    ///
476    /// ```
477    /// use abi_stable::std_types::RSliceMut;
478    ///
479    /// assert_eq!(
480    ///     RSliceMut::from_mut_slice(&mut [0, 1, 2, 3]).into_mut_slice(),
481    ///     &mut [0, 1, 2, 3]
482    /// );
483    ///
484    /// ```
485    pub fn into_mut_slice(mut self) -> &'a mut [T] {
486        unsafe { self.as_mut_slice_unbounded_lifetime() }
487    }
488}
489
490unsafe impl<'a, T> Send for RSliceMut<'a, T> where &'a mut [T]: Send {}
491unsafe impl<'a, T> Sync for RSliceMut<'a, T> where &'a mut [T]: Sync {}
492
493impl<'a, T> Default for RSliceMut<'a, T> {
494    fn default() -> Self {
495        (&mut [][..]).into()
496    }
497}
498
499impl<'a, T> IntoIterator for RSliceMut<'a, T> {
500    type Item = &'a mut T;
501
502    type IntoIter = ::std::slice::IterMut<'a, T>;
503
504    fn into_iter(self) -> ::std::slice::IterMut<'a, T> {
505        self.into_mut_slice().iter_mut()
506    }
507}
508
509slice_like_impl_cmp_traits! {
510    impl[] RSliceMut<'_, T>,
511    where[];
512    Vec<U>,
513    [U],
514    &[U],
515    RSlice<'_, U>,
516}
517
518slice_like_impl_cmp_traits! {
519    impl[const N: usize] RSliceMut<'_, T>,
520    where[];
521    [U; N],
522}
523
524slice_like_impl_cmp_traits! {
525    impl[] RSliceMut<'_, T>,
526    where[T: Clone, U: Clone];
527    std::borrow::Cow<'_, [U]>,
528    crate::std_types::RCowSlice<'_, U>,
529}
530
531impl<'a, T> Deref for RSliceMut<'a, T> {
532    type Target = [T];
533
534    fn deref(&self) -> &Self::Target {
535        self.as_slice()
536    }
537}
538
539impl<'a, T> DerefMut for RSliceMut<'a, T> {
540    fn deref_mut(&mut self) -> &mut Self::Target {
541        self.as_mut_slice()
542    }
543}
544
545////////////////////////////
546
547impl_into_rust_repr! {
548    impl['a, T] Into<&'a mut [T]> for RSliceMut<'a, T> {
549        fn(this){
550            this.into_mut_slice()
551        }
552    }
553}
554
555impl<'a, T> From<RSliceMut<'a, T>> for &'a [T] {
556    fn from(this: RSliceMut<'a, T>) -> &'a [T] {
557        this.into_slice()
558    }
559}
560
561////////////////////
562
563impl<'a, T: 'a> Borrow<[T]> for RSliceMut<'a, T> {
564    fn borrow(&self) -> &[T] {
565        self
566    }
567}
568
569impl<'a, T: 'a> BorrowMut<[T]> for RSliceMut<'a, T> {
570    fn borrow_mut(&mut self) -> &mut [T] {
571        self
572    }
573}
574
575impl<'a, T: 'a> AsRef<[T]> for RSliceMut<'a, T> {
576    fn as_ref(&self) -> &[T] {
577        self
578    }
579}
580
581impl<'a, T: 'a> AsMut<[T]> for RSliceMut<'a, T> {
582    fn as_mut(&mut self) -> &mut [T] {
583        self
584    }
585}
586
587impl<'a, T, I: SliceIndex<[T]>> Index<I> for RSliceMut<'a, T> {
588    type Output = I::Output;
589
590    #[inline]
591    fn index(&self, index: I) -> &Self::Output {
592        Index::index(&**self, index)
593    }
594}
595
596impl<'a, T, I: SliceIndex<[T]>> IndexMut<I> for RSliceMut<'a, T> {
597    #[inline]
598    fn index_mut(&mut self, index: I) -> &mut Self::Output {
599        IndexMut::index_mut(&mut **self, index)
600    }
601}
602
603////////////////////////////
604impl<'a, T> Serialize for RSliceMut<'a, T>
605where
606    T: Serialize,
607{
608    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
609    where
610        S: Serializer,
611    {
612        self.as_slice().serialize(serializer)
613    }
614}
615
616///////////////////////////////////////////////////////////////////////////////
617
618impl<'a> Write for RSliceMut<'a, u8> {
619    #[inline]
620    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
621        let mut this = mem::take(self).into_mut_slice();
622        let ret = this.write(data);
623        *self = this.into();
624        ret
625    }
626
627    #[inline]
628    fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
629        let mut this = mem::take(self).into_mut_slice();
630        let ret = this.write_all(data);
631        *self = this.into();
632        ret
633    }
634
635    #[inline]
636    fn flush(&mut self) -> io::Result<()> {
637        Ok(())
638    }
639}
640
641///////////////////////////////////////////////////////////////////////////////
642
643#[allow(dead_code)]
644type SliceMut<'a, T> = &'a mut [T];
645
646shared_impls! {
647    mod = slice_impls
648    new_type = RSliceMut['a][T],
649    original_type = SliceMut,
650}
651
652////////////////////////////////////////////////////////////////////////////////
653
654//#[cfg(test)]
655#[cfg(all(test, not(feature = "only_new_tests")))]
656mod test {
657    use super::*;
658
659    #[test]
660    fn from_to_slice() {
661        let a = b"what the hell".to_vec();
662        let mut a_clone = a.clone();
663        let a_addr = a_clone.as_ptr();
664        let mut b = RSliceMut::from(&mut a_clone[..]);
665
666        assert_eq!(&*a, &*b);
667        assert_eq!(&*a, &mut *b);
668        assert_eq!(a_addr, b.data());
669        assert_eq!(a.len(), b.len());
670    }
671
672    #[cfg(feature = "rust_1_64")]
673    #[test]
674    fn const_as_slice_test() {
675        const RSM: RSliceMut<'_, u8> =
676            unsafe { RSliceMut::from_raw_parts_mut(std::ptr::NonNull::dangling().as_ptr(), 0) };
677
678        const SLICE_A: &[u8] = RSM.as_slice();
679        const SLICE_B: &[u8] = RSM.into_slice();
680
681        assert_eq!(SLICE_A, [0u8; 0]);
682        assert_eq!(SLICE_B, [0u8; 0]);
683    }
684
685    #[test]
686    fn test_index() {
687        let mut v = vec![1, 2, 3, 4, 5];
688        let s = RSliceMut::from_mut_slice(&mut v[..]);
689
690        assert_eq!(s.index(0), &1);
691        assert_eq!(s.index(4), &5);
692        assert_eq!(s.index(..2), &mut [1, 2]);
693        assert_eq!(s.index(1..2), &mut [2]);
694        assert_eq!(s.index(3..), &mut [4, 5]);
695    }
696
697    #[test]
698    fn test_index_mut() {
699        let mut v = vec![1, 2, 3, 4, 5];
700        let mut s = RSliceMut::from_mut_slice(&mut v[..]);
701
702        assert_eq!(s.index_mut(0), &mut 1);
703        assert_eq!(s.index_mut(4), &mut 5);
704        assert_eq!(s.index_mut(..2), &mut [1, 2]);
705        assert_eq!(s.index_mut(1..2), &mut [2]);
706        assert_eq!(s.index_mut(3..), &mut [4, 5]);
707    }
708}