1 use core::ops::{Deref, DerefMut}; 2 use core::fmt; 3 4 #[cfg(feature = "std")] 5 use std::boxed::Box; 6 #[cfg(all(feature = "alloc", not(feature = "std")))] 7 use alloc::boxed::Box; 8 #[cfg(feature = "std")] 9 use std::vec::Vec; 10 #[cfg(all(feature = "alloc", not(feature = "std")))] 11 use alloc::vec::Vec; 12 13 /// A managed slice. 14 /// 15 /// This enum can be used to represent exclusive access to slices of objects. 16 /// In Rust, exclusive access to an object is obtained by either owning the object, 17 /// or owning a mutable pointer to the object; hence, "managed". 18 /// 19 /// The purpose of this enum is providing good ergonomics with `std` present while making 20 /// it possible to avoid having a heap at all (which of course means that `std` is not present). 21 /// To achieve this, the variants other than `Borrowed` are only available when the corresponding 22 /// feature is opted in. 23 /// 24 /// A function that requires a managed object should be generic over an `Into<ManagedSlice<'a, T>>` 25 /// argument; then, it will be possible to pass either a `Vec<T>`, or a `&'a mut [T]` 26 /// without any conversion at the call site. 27 /// 28 /// See also [Managed](enum.Managed.html). 29 pub enum ManagedSlice<'a, T: 'a> { 30 /// Borrowed variant. 31 Borrowed(&'a mut [T]), 32 /// Owned variant, only available with the `std` or `alloc` feature enabled. 33 #[cfg(any(feature = "std", feature = "alloc"))] 34 Owned(Vec<T>) 35 } 36 37 impl<'a, T: 'a> fmt::Debug for ManagedSlice<'a, T> 38 where T: fmt::Debug { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 40 match self { 41 &ManagedSlice::Borrowed(ref x) => write!(f, "Borrowed({:?})", x), 42 #[cfg(any(feature = "std", feature = "alloc"))] 43 &ManagedSlice::Owned(ref x) => write!(f, "Owned({:?})", x) 44 } 45 } 46 } 47 48 impl<'a, T: 'a> From<&'a mut [T]> for ManagedSlice<'a, T> { from(value: &'a mut [T]) -> Self49 fn from(value: &'a mut [T]) -> Self { 50 ManagedSlice::Borrowed(value) 51 } 52 } 53 54 macro_rules! from_unboxed_slice { 55 ($n:expr) => ( 56 impl<'a, T> From<[T; $n]> for ManagedSlice<'a, T> { 57 #[inline] 58 fn from(value: [T; $n]) -> Self { 59 ManagedSlice::Owned((Box::new(value) as Box<[T]>).into_vec()) 60 } 61 } 62 ); 63 ($n:expr, $( $r:expr ),*) => ( 64 from_unboxed_slice!($n); 65 from_unboxed_slice!($( $r ),*); 66 ) 67 } 68 69 #[cfg(any(feature = "std", feature = "alloc"))] 70 from_unboxed_slice!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 71 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31); 72 73 #[cfg(any(feature = "std", feature = "alloc"))] 74 impl<'a, T: 'a> From<Vec<T>> for ManagedSlice<'a, T> { from(value: Vec<T>) -> Self75 fn from(value: Vec<T>) -> Self { 76 ManagedSlice::Owned(value) 77 } 78 } 79 80 impl<'a, T: 'a> Deref for ManagedSlice<'a, T> { 81 type Target = [T]; 82 deref(&self) -> &Self::Target83 fn deref(&self) -> &Self::Target { 84 match self { 85 &ManagedSlice::Borrowed(ref value) => value, 86 #[cfg(any(feature = "std", feature = "alloc"))] 87 &ManagedSlice::Owned(ref value) => value 88 } 89 } 90 } 91 92 impl<'a, T: 'a> DerefMut for ManagedSlice<'a, T> { deref_mut(&mut self) -> &mut Self::Target93 fn deref_mut(&mut self) -> &mut Self::Target { 94 match self { 95 &mut ManagedSlice::Borrowed(ref mut value) => value, 96 #[cfg(any(feature = "std", feature = "alloc"))] 97 &mut ManagedSlice::Owned(ref mut value) => value 98 } 99 } 100 } 101