managed/
object.rs

1use core::ops::{Deref, DerefMut};
2use core::fmt;
3
4#[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;
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.
31pub 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
39impl<'a, T: 'a + ?Sized> fmt::Debug for Managed<'a, T>
40        where T: fmt::Debug {
41    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
50impl<'a, T: 'a + ?Sized> From<&'a mut T> for Managed<'a, T> {
51    fn from(value: &'a mut T) -> Self {
52        Managed::Borrowed(value)
53    }
54}
55
56#[cfg(any(feature = "std", feature = "alloc"))]
57impl<'a, T: ?Sized + 'a> From<Box<T>> for Managed<'a, T> {
58    fn from(value: Box<T>) -> Self {
59        Managed::Owned(value)
60    }
61}
62
63#[cfg(any(feature = "std", feature = "alloc"))]
64impl<'a, T: 'a> From<Vec<T>> for Managed<'a, [T]> {
65    fn from(value: Vec<T>) -> Self {
66        Managed::Owned(value.into_boxed_slice())
67    }
68}
69
70impl<'a, T: 'a + ?Sized> Deref for Managed<'a, T> {
71    type Target = T;
72
73    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
82impl<'a, T: 'a + ?Sized> DerefMut for Managed<'a, T> {
83    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}