differential_dataflow/
into_owned.rs

1//! Traits for converting between owned and borrowed types.
2
3/// A reference type corresponding to an owned type, supporting conversion in each direction.
4///
5/// This trait can be implemented by a GAT, and enables owned types to be borrowed as a GAT.
6/// This trait is analogous to `ToOwned`, but not as prescriptive. Specifically, it avoids the
7/// requirement that the other trait implement `Borrow`, for which a borrow must result in a
8/// `&'self Borrowed`, which cannot move the lifetime into a GAT borrowed type.
9pub trait IntoOwned<'a> {
10    /// Owned type into which this type can be converted.
11    type Owned;
12    /// Conversion from an instance of this type to the owned type.
13    #[must_use]
14    fn into_owned(self) -> Self::Owned;
15    /// Clones `self` onto an existing instance of the owned type.
16    fn clone_onto(self, other: &mut Self::Owned);
17    /// Borrows an owned instance as oneself.
18    #[must_use]
19    fn borrow_as(owned: &'a Self::Owned) -> Self;
20}
21
22impl<'a, T: ToOwned + ?Sized> IntoOwned<'a> for &'a T {
23    type Owned = T::Owned;
24    #[inline]
25    fn into_owned(self) -> Self::Owned {
26        self.to_owned()
27    }
28    #[inline]
29    fn clone_onto(self, other: &mut Self::Owned) {
30        <T as ToOwned>::clone_into(self, other)
31    }
32    #[inline]
33    fn borrow_as(owned: &'a Self::Owned) -> Self {
34        std::borrow::Borrow::borrow(owned)
35    }
36}
37
38impl<'a, T, E> IntoOwned<'a> for Result<T, E>
39where
40    T: IntoOwned<'a>,
41    E: IntoOwned<'a>,
42{
43    type Owned = Result<T::Owned, E::Owned>;
44
45    #[inline]
46    fn into_owned(self) -> Self::Owned {
47        self.map(T::into_owned).map_err(E::into_owned)
48    }
49
50    #[inline]
51    fn clone_onto(self, other: &mut Self::Owned) {
52        match (self, other) {
53            (Ok(item), Ok(target)) => T::clone_onto(item, target),
54            (Err(item), Err(target)) => E::clone_onto(item, target),
55            (Ok(item), target) => *target = Ok(T::into_owned(item)),
56            (Err(item), target) => *target = Err(E::into_owned(item)),
57        }
58    }
59
60    #[inline]
61    fn borrow_as(owned: &'a Self::Owned) -> Self {
62        owned.as_ref().map(T::borrow_as).map_err(E::borrow_as)
63    }
64}
65
66impl<'a, T> IntoOwned<'a> for Option<T>
67where
68    T: IntoOwned<'a>,
69{
70    type Owned = Option<T::Owned>;
71
72    #[inline]
73    fn into_owned(self) -> Self::Owned {
74        self.map(IntoOwned::into_owned)
75    }
76
77    #[inline]
78    fn clone_onto(self, other: &mut Self::Owned) {
79        match (self, other) {
80            (Some(item), Some(target)) => T::clone_onto(item, target),
81            (Some(item), target) => *target = Some(T::into_owned(item)),
82            (None, target) => *target = None,
83        }
84    }
85
86    #[inline]
87    fn borrow_as(owned: &'a Self::Owned) -> Self {
88        owned.as_ref().map(T::borrow_as)
89    }
90}
91
92mod tuple {
93    use paste::paste;
94
95    macro_rules! tuple {
96        ($($name:ident)+) => (paste! {
97
98            #[allow(non_camel_case_types)]
99            #[allow(non_snake_case)]
100            impl<'a, $($name),*> crate::IntoOwned<'a> for ($($name,)*)
101            where
102                $($name: crate::IntoOwned<'a>),*
103            {
104                type Owned = ($($name::Owned,)*);
105
106                #[inline]
107                fn into_owned(self) -> Self::Owned {
108                    let ($($name,)*) = self;
109                    (
110                        $($name.into_owned(),)*
111                    )
112                }
113
114                #[inline]
115                fn clone_onto(self, other: &mut Self::Owned) {
116                    let ($($name,)*) = self;
117                    let ($([<$name _other>],)*) = other;
118                    $($name.clone_onto([<$name _other>]);)*
119                }
120
121                #[inline]
122                fn borrow_as(owned: &'a Self::Owned) -> Self {
123                    let ($($name,)*) = owned;
124                    (
125                        $($name::borrow_as($name),)*
126                    )
127                }
128            }
129        })
130    }
131
132    tuple!(A);
133    tuple!(A B);
134    tuple!(A B C);
135    tuple!(A B C D);
136    tuple!(A B C D E);
137    tuple!(A B C D E F);
138    tuple!(A B C D E F G);
139    tuple!(A B C D E F G H);
140    tuple!(A B C D E F G H I);
141    tuple!(A B C D E F G H I J);
142    tuple!(A B C D E F G H I J K);
143    tuple!(A B C D E F G H I J K L);
144    tuple!(A B C D E F G H I J K L M);
145    tuple!(A B C D E F G H I J K L M N);
146    tuple!(A B C D E F G H I J K L M N O);
147    tuple!(A B C D E F G H I J K L M N O P);
148}
149
150mod primitive {
151    macro_rules! implement_for {
152    ($index_type:ty) => {
153        impl<'a> crate::IntoOwned<'a> for $index_type {
154            type Owned = $index_type;
155
156            #[inline]
157            fn into_owned(self) -> Self::Owned {
158                self
159            }
160
161            #[inline]
162            fn clone_onto(self, other: &mut Self::Owned) {
163                *other = self;
164            }
165
166            #[inline]
167            fn borrow_as(owned: &'a Self::Owned) -> Self {
168                *owned
169            }
170        }
171    };
172}
173
174    implement_for!(());
175    implement_for!(bool);
176    implement_for!(char);
177
178    implement_for!(u8);
179    implement_for!(u16);
180    implement_for!(u32);
181    implement_for!(u64);
182    implement_for!(u128);
183    implement_for!(usize);
184
185    implement_for!(i8);
186    implement_for!(i16);
187    implement_for!(i32);
188    implement_for!(i64);
189    implement_for!(i128);
190    implement_for!(isize);
191
192    implement_for!(f32);
193    implement_for!(f64);
194
195    implement_for!(std::num::Wrapping<i8>);
196    implement_for!(std::num::Wrapping<i16>);
197    implement_for!(std::num::Wrapping<i32>);
198    implement_for!(std::num::Wrapping<i64>);
199    implement_for!(std::num::Wrapping<i128>);
200    implement_for!(std::num::Wrapping<isize>);
201
202    implement_for!(std::time::Duration);
203
204}