Skip to main content

der/
referenced.rs

1//! A module for working with referenced data.
2
3/// A trait for borrowing data from an owned struct
4///
5/// This converts an object owning the data to one that will borrowing the content.
6/// The newly created object lifetime will be tied to the object owning the data.
7///
8/// This is similar to [`alloc::borrow::Borrow`] or [`core::convert::AsRef`] but this returns
9/// an owned structure that references directly the backing slices instead of borrowing
10/// the whole structure.
11pub trait OwnedToRef {
12    /// The resulting type referencing back to Self
13    type Borrowed<'a>
14    where
15        Self: 'a;
16
17    /// Creates a new object referencing back to the self for storage
18    fn owned_to_ref(&self) -> Self::Borrowed<'_>;
19}
20
21/// A trait for cloning a referenced structure and getting owned objects
22///
23/// This is the pendant to [`OwnedToRef`].
24///
25/// This converts an object borrowing data to one that will copy the data over and
26/// own the content.
27pub trait RefToOwned<'a> {
28    /// The resulting type after obtaining ownership.
29    type Owned: OwnedToRef<Borrowed<'a> = Self>
30    where
31        Self: 'a;
32
33    /// Creates a new object taking ownership of the data
34    fn ref_to_owned(&self) -> Self::Owned;
35}
36
37impl<T> OwnedToRef for Option<T>
38where
39    T: OwnedToRef,
40{
41    type Borrowed<'a>
42        = Option<T::Borrowed<'a>>
43    where
44        T: 'a;
45
46    #[allow(clippy::redundant_closure_for_method_calls, reason = "MSRV")]
47    fn owned_to_ref(&self) -> Self::Borrowed<'_> {
48        self.as_ref().map(|o| o.owned_to_ref())
49    }
50}
51
52impl<'a, T> RefToOwned<'a> for Option<T>
53where
54    T: RefToOwned<'a> + 'a,
55    T::Owned: OwnedToRef,
56{
57    type Owned = Option<T::Owned>;
58
59    #[allow(clippy::redundant_closure_for_method_calls, reason = "MSRV")]
60    fn ref_to_owned(&self) -> Self::Owned {
61        self.as_ref().map(|o| o.ref_to_owned())
62    }
63}
64
65#[cfg(feature = "alloc")]
66mod allocating {
67    use super::{OwnedToRef, RefToOwned};
68    use alloc::boxed::Box;
69
70    impl<'a> RefToOwned<'a> for &'a [u8] {
71        type Owned = Box<[u8]>;
72
73        fn ref_to_owned(&self) -> Self::Owned {
74            Box::from(*self)
75        }
76    }
77
78    impl OwnedToRef for Box<[u8]> {
79        type Borrowed<'a> = &'a [u8];
80
81        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
82            self.as_ref()
83        }
84    }
85}