1use core::ops::{Deref, DerefMut};
2use core::fmt;
34#[cfg(feature = "std")]
5use std::boxed::Box;
6#[cfg(all(feature = "alloc", not(feature = "std")))]
7use alloc::boxed::Box;
8#[cfg(feature = "std")]
9use std::vec::Vec;
10#[cfg(all(feature = "alloc", not(feature = "std")))]
11use alloc::vec::Vec;
1213/// 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.
31pub enum Managed<'a, T: 'a + ?Sized> {
32/// Borrowed variant.
33Borrowed(&'a mut T),
34/// Owned variant, only available with the `std` or `alloc` feature enabled.
35#[cfg(any(feature = "std", feature = "alloc"))]
36Owned(Box<T>)
37}
3839impl<'a, T: 'a + ?Sized> fmt::Debug for Managed<'a, T>
40where T: fmt::Debug {
41fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42match 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}
4950impl<'a, T: 'a + ?Sized> From<&'a mut T> for Managed<'a, T> {
51fn from(value: &'a mut T) -> Self {
52 Managed::Borrowed(value)
53 }
54}
5556#[cfg(any(feature = "std", feature = "alloc"))]
57impl<'a, T: ?Sized + 'a> From<Box<T>> for Managed<'a, T> {
58fn from(value: Box<T>) -> Self {
59 Managed::Owned(value)
60 }
61}
6263#[cfg(any(feature = "std", feature = "alloc"))]
64impl<'a, T: 'a> From<Vec<T>> for Managed<'a, [T]> {
65fn from(value: Vec<T>) -> Self {
66 Managed::Owned(value.into_boxed_slice())
67 }
68}
6970impl<'a, T: 'a + ?Sized> Deref for Managed<'a, T> {
71type Target = T;
7273fn deref(&self) -> &Self::Target {
74match self {
75&Managed::Borrowed(ref value) => value,
76#[cfg(any(feature = "std", feature = "alloc"))]
77&Managed::Owned(ref value) => value
78 }
79 }
80}
8182impl<'a, T: 'a + ?Sized> DerefMut for Managed<'a, T> {
83fn deref_mut(&mut self) -> &mut Self::Target {
84match 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}