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 object. 14 /// 15 /// This enum can be used to represent exclusive access to objects. In Rust, exclusive access 16 /// to an object is obtained by either owning the object, or owning a mutable pointer 17 /// 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 `Borrow` 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<Managed<'a, T>>` 25 /// argument; then, it will be possible to pass either a `Box<T>`, `Vec<T>`, or a `&'a mut T` 26 /// without any conversion at the call site. 27 /// 28 /// Note that a `Vec<T>` converted into an `Into<Managed<'a, [T]>>` gets transformed 29 /// into a boxed slice, and can no longer be resized. See also 30 /// [ManagedSlice](enum.ManagedSlice.html), which does not have this drawback. 31 pub enum Managed<'a, T: 'a + ?Sized> { 32 /// Borrowed variant. 33 Borrowed(&'a mut T), 34 /// Owned variant, only available with the `std` or `alloc` feature enabled. 35 #[cfg(any(feature = "std", feature = "alloc"))] 36 Owned(Box<T>) 37 } 38 39 impl<'a, T: 'a + ?Sized> fmt::Debug for Managed<'a, T> 40 where T: fmt::Debug { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 42 match self { 43 &Managed::Borrowed(ref x) => write!(f, "Borrowed({:?})", x), 44 #[cfg(any(feature = "std", feature = "alloc"))] 45 &Managed::Owned(ref x) => write!(f, "Owned({:?})", x) 46 } 47 } 48 } 49 50 impl<'a, T: 'a + ?Sized> From<&'a mut T> for Managed<'a, T> { from(value: &'a mut T) -> Self51 fn from(value: &'a mut T) -> Self { 52 Managed::Borrowed(value) 53 } 54 } 55 56 #[cfg(any(feature = "std", feature = "alloc"))] 57 impl<'a, T: ?Sized + 'a> From<Box<T>> for Managed<'a, T> { from(value: Box<T>) -> Self58 fn from(value: Box<T>) -> Self { 59 Managed::Owned(value) 60 } 61 } 62 63 #[cfg(any(feature = "std", feature = "alloc"))] 64 impl<'a, T: 'a> From<Vec<T>> for Managed<'a, [T]> { from(value: Vec<T>) -> Self65 fn from(value: Vec<T>) -> Self { 66 Managed::Owned(value.into_boxed_slice()) 67 } 68 } 69 70 impl<'a, T: 'a + ?Sized> Deref for Managed<'a, T> { 71 type Target = T; 72 deref(&self) -> &Self::Target73 fn deref(&self) -> &Self::Target { 74 match self { 75 &Managed::Borrowed(ref value) => value, 76 #[cfg(any(feature = "std", feature = "alloc"))] 77 &Managed::Owned(ref value) => value 78 } 79 } 80 } 81 82 impl<'a, T: 'a + ?Sized> DerefMut for Managed<'a, T> { deref_mut(&mut self) -> &mut Self::Target83 fn deref_mut(&mut self) -> &mut Self::Target { 84 match self { 85 &mut Managed::Borrowed(ref mut value) => value, 86 #[cfg(any(feature = "std", feature = "alloc"))] 87 &mut Managed::Owned(ref mut value) => value 88 } 89 } 90 } 91