• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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