ownref/
box_owned.rs

1use crate::{arc_owned::ArcOwned, arc_ref::ArcRef, box_ref::BoxRef, marker::*};
2use std::{
3    any::Any,
4    borrow::Borrow,
5    cmp, fmt,
6    fmt::{Debug, Display},
7    hash::{Hash, Hasher},
8    marker::PhantomData,
9    ops::{Deref, DerefMut},
10    ptr,
11};
12
13/// Content ordered owned data bundled with an owner in [Box].
14pub type BoxOwnedC<'a, O, I = &'a mut O> = BoxOwned<'a, O, I, ByContent>;
15
16/// Pointer address ordered owned data bundled with an owner in [Box].
17pub type BoxOwnedA<'a, O, I = &'a mut O> = BoxOwned<'a, O, I, ByAddress>;
18
19/// Content ordered owned data bundled with an [Any] + [Send] owner in [Box].
20pub type BoxOwnedAnyC<'a, I> = BoxOwned<'a, dyn Any + Send + 'static, I, ByContent>;
21
22/// Pointer address ordered owned data bundled with an [Any] + [Send] owner in [Box].
23pub type BoxOwnedAnyA<'a, I> = BoxOwned<'a, dyn Any + Send + 'static, I, ByAddress>;
24
25/// Content ordered owned data bundled with an [Any] owner in [Box].
26pub type BoxOwnedAnyLocalC<'a, I> = BoxOwned<'a, dyn Any + 'static, I, ByContent>;
27
28/// Pointer address ordered owned data bundled with an [Any] owner in [Box].
29pub type BoxOwnedAnyLocalA<'a, I> = BoxOwned<'a, dyn Any + 'static, I, ByAddress>;
30
31/// Owned data bundled with an owner in [Box].
32pub struct BoxOwned<'a, O, I, E>
33where
34    O: ?Sized,
35    E: EqKind,
36{
37    // inner goes before owner so that inner drops before owner
38    pub(crate) _phantom: PhantomData<(&'a I, E)>,
39    pub(crate) inner: I,
40    pub(crate) owner: Box<O>,
41}
42
43impl<'a, O, E> BoxOwned<'a, O, &'a mut O, E>
44where
45    O: ?Sized,
46    E: EqKind,
47{
48    /// Build from boxed data.
49    pub fn from_box(owner: Box<O>) -> Self {
50        owner.into()
51    }
52}
53
54impl<'a, O, I, E> BoxOwned<'a, O, I, E>
55where
56    O: ?Sized,
57    E: EqKind,
58{
59    /// Discard owned data and return boxed owner.
60    pub fn into_box(from: BoxOwned<'a, O, I, E>) -> Box<O> {
61        let Self { owner, inner, .. } = from;
62        drop(inner);
63        owner
64    }
65
66    /// Convert to [ArcOwned] without re-allocation.
67    pub fn into_arc_owned(from: BoxOwned<'a, O, I, E>) -> ArcOwned<'a, O, I, E> {
68        let Self { owner, inner, .. } = from;
69        ArcOwned {
70            owner: owner.into(),
71            inner,
72            _phantom: PhantomData,
73        }
74    }
75
76    /// Reset data to the reference to owner.
77    pub fn into_owner_ref(this: BoxOwned<'a, O, I, E>) -> BoxOwned<'a, O, &mut O, E> {
78        let Self {
79            mut owner, inner, ..
80        } = this;
81        drop(inner);
82
83        unsafe {
84            // re-borrow to obtain 'a lifetime
85            let inner = &mut *(owner.as_mut() as *mut O);
86
87            BoxOwned {
88                inner,
89                owner,
90                _phantom: PhantomData,
91            }
92        }
93    }
94
95    /// Get the reference to owner.
96    pub fn owner(this: &'a BoxOwned<'a, O, I, E>) -> &'a O {
97        &this.owner
98    }
99
100    /// Applies function `f` to data.
101    pub fn map<T, F>(self, f: F) -> BoxOwned<'a, O, T, E>
102    where
103        F: FnOnce(I) -> T,
104    {
105        let Self { owner, inner, .. } = self;
106
107        BoxOwned {
108            owner,
109            inner: f(inner),
110            _phantom: PhantomData,
111        }
112    }
113
114    /// Applies fallible function `f` to data.
115    pub fn try_map<Ok, Err, F>(self, f: F) -> Result<BoxOwned<'a, O, Ok, E>, Err>
116    where
117        F: FnOnce(I) -> Result<Ok, Err>,
118    {
119        let Self { owner, inner, .. } = self;
120
121        Ok(BoxOwned {
122            owner,
123            inner: f(inner)?,
124            _phantom: PhantomData,
125        })
126    }
127
128    /// Applies function `f` that returns optional value to data.
129    pub fn filter_map<T, F>(self, f: F) -> Option<BoxOwned<'a, O, T, E>>
130    where
131        F: FnOnce(I) -> Option<T>,
132    {
133        let Self { owner, inner, .. } = self;
134
135        Some(BoxOwned {
136            owner,
137            inner: f(inner)?,
138            _phantom: PhantomData,
139        })
140    }
141}
142
143impl<'a, O, I, E> BoxOwned<'a, O, I, E>
144where
145    E: EqKind,
146{
147    /// Build from an owner.
148    pub fn new(owner: O) -> Self
149    where
150        Self: From<Box<O>>,
151    {
152        Box::new(owner).into()
153    }
154
155    /// Discard the data and return the owner.
156    pub fn into_owner(from: BoxOwned<'a, O, I, E>) -> O {
157        let Self { owner, inner, .. } = from;
158        drop(inner);
159        *owner
160    }
161
162    /// Change the owner type to [Any] + [Send] trait object.
163    pub fn into_any_owner(
164        from: BoxOwned<'a, O, I, E>,
165    ) -> BoxOwned<'a, dyn Any + Send + 'static, I, E>
166    where
167        O: Send + 'static,
168    {
169        let Self { owner, inner, .. } = from;
170
171        BoxOwned {
172            inner,
173            owner,
174            _phantom: PhantomData,
175        }
176    }
177
178    /// Change the owner type to [Any] trait object.
179    pub fn into_any_owner_local(
180        from: BoxOwned<'a, O, I, E>,
181    ) -> BoxOwned<'a, dyn Any + 'static, I, E>
182    where
183        O: 'static,
184    {
185        let Self { owner, inner, .. } = from;
186
187        BoxOwned {
188            inner,
189            owner,
190            _phantom: PhantomData,
191        }
192    }
193}
194
195impl<'a, O, I, E> BoxOwned<'a, O, &'a mut I, E>
196where
197    O: ?Sized,
198    I: ?Sized,
199    E: EqKind,
200{
201    /// Convert to [BoxRef].
202    pub fn into_box_ref(self) -> BoxRef<'a, O, I, E> {
203        let Self { owner, inner, .. } = self;
204
205        BoxRef {
206            owner,
207            inner,
208            _phantom: PhantomData,
209        }
210    }
211
212    /// Convert to [ArcRef].
213    pub fn into_arc_ref(self) -> ArcRef<'a, O, I, E> {
214        let Self { owner, inner, .. } = self;
215
216        ArcRef {
217            owner: owner.into(),
218            inner,
219            _phantom: PhantomData,
220        }
221    }
222}
223
224impl<'a, O, I, E> BoxOwned<'a, O, &'a I, E>
225where
226    O: ?Sized,
227    I: ?Sized,
228    E: EqKind,
229{
230    /// Convert to [ArcRef].
231    pub fn into_arc_ref(self) -> ArcRef<'a, O, I, E> {
232        let Self { owner, inner, .. } = self;
233
234        ArcRef {
235            owner: owner.into(),
236            inner,
237            _phantom: PhantomData,
238        }
239    }
240}
241
242impl<'a, O, I, E> BoxOwned<'a, O, Option<I>, E>
243where
244    O: ?Sized,
245    E: EqKind,
246{
247    /// Transpose an [BoxOwned] of a [Option] to a [Option] of an [BoxOwned].
248    pub fn transpose(self) -> Option<BoxOwned<'a, O, I, E>> {
249        let Self { owner, inner, .. } = self;
250        Some(BoxOwned {
251            owner,
252            inner: inner?,
253            _phantom: PhantomData,
254        })
255    }
256}
257
258impl<'a, O, Ok, Err, E> BoxOwned<'a, O, Result<Ok, Err>, E>
259where
260    O: ?Sized,
261    E: EqKind,
262{
263    /// Transpose an [BoxOwned] of a [Result] to a [Result] of an [BoxOwned].
264    pub fn transpose(self) -> Result<BoxOwned<'a, O, Ok, E>, Err> {
265        let Self { owner, inner, .. } = self;
266        Ok(BoxOwned {
267            owner,
268            inner: inner?,
269            _phantom: PhantomData,
270        })
271    }
272}
273
274impl<'a, I, E> BoxOwned<'a, dyn Any + Send + 'static, I, E>
275where
276    E: EqKind,
277{
278    /// Downcast the [Any] + [Send] trait object owner to concrete type.
279    pub fn downcast_owner<O>(this: Self) -> Result<BoxOwned<'a, O, I, E>, Self>
280    where
281        O: Send + 'static,
282    {
283        let Self { owner, inner, .. } = this;
284
285        match owner.downcast() {
286            Ok(owner) => Ok(BoxOwned {
287                owner,
288                inner,
289                _phantom: PhantomData,
290            }),
291            Err(owner) => Err(BoxOwned {
292                owner,
293                inner,
294                _phantom: PhantomData,
295            }),
296        }
297    }
298}
299
300impl<'a, I, E> BoxOwned<'a, dyn Any + 'static, I, E>
301where
302    E: EqKind,
303{
304    /// Downcast the [Any] trait object owner to concrete type.
305    pub fn downcast_owner_local<O>(this: Self) -> Result<BoxOwned<'a, O, I, E>, Self>
306    where
307        O: 'static,
308    {
309        let Self { owner, inner, .. } = this;
310
311        match owner.downcast() {
312            Ok(owner) => Ok(BoxOwned {
313                owner,
314                inner,
315                _phantom: PhantomData,
316            }),
317            Err(owner) => Err(BoxOwned {
318                owner,
319                inner,
320                _phantom: PhantomData,
321            }),
322        }
323    }
324}
325
326impl<'a, O, I, E> Debug for BoxOwned<'a, O, I, E>
327where
328    O: ?Sized,
329    I: Debug,
330    E: EqKind,
331{
332    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
333        self.inner.fmt(f)
334    }
335}
336
337impl<'a, O, I, E> Display for BoxOwned<'a, O, I, E>
338where
339    O: ?Sized,
340    I: Display,
341    E: EqKind,
342{
343    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
344        self.inner.fmt(f)
345    }
346}
347
348impl<'a, O, I> PartialEq<Self> for BoxOwned<'a, O, I, ByContent>
349where
350    O: ?Sized,
351    I: PartialEq<I>,
352{
353    fn eq(&self, other: &Self) -> bool {
354        self.inner.eq(&other.inner)
355    }
356}
357
358impl<'a, O, I> Eq for BoxOwned<'a, O, I, ByContent>
359where
360    I: Eq,
361    O: ?Sized,
362{
363}
364
365impl<'a, O, I> PartialOrd<Self> for BoxOwned<'a, O, I, ByContent>
366where
367    O: ?Sized,
368    I: PartialOrd<I>,
369{
370    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
371        self.inner.partial_cmp(&other.inner)
372    }
373}
374
375impl<'a, O, I> Ord for BoxOwned<'a, O, I, ByContent>
376where
377    O: ?Sized,
378    I: Ord,
379{
380    fn cmp(&self, other: &Self) -> cmp::Ordering {
381        self.inner.cmp(&other.inner)
382    }
383}
384
385impl<'a, O, I> Hash for BoxOwned<'a, O, I, ByContent>
386where
387    O: ?Sized,
388    I: Hash,
389{
390    fn hash<H>(&self, state: &mut H)
391    where
392        H: Hasher,
393    {
394        self.inner.hash(state);
395    }
396}
397
398impl<'a, O, I> PartialEq<Self> for BoxOwned<'a, O, &'a mut I, ByAddress>
399where
400    O: ?Sized,
401    I: ?Sized,
402{
403    fn eq(&self, other: &Self) -> bool {
404        ptr::eq(self.inner as *const I, other.inner as *const I)
405    }
406}
407
408impl<'a, O, I> Eq for BoxOwned<'a, O, &'a mut I, ByAddress>
409where
410    O: ?Sized,
411    I: ?Sized,
412{
413}
414
415impl<'a, O, I> PartialOrd<Self> for BoxOwned<'a, O, &'a mut I, ByAddress>
416where
417    O: ?Sized,
418    I: ?Sized,
419{
420    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
421        (self.inner as *const I).partial_cmp(&(other.inner as *const I))
422    }
423}
424
425impl<'a, O, I> Ord for BoxOwned<'a, O, &'a mut I, ByAddress>
426where
427    O: ?Sized,
428    I: ?Sized,
429{
430    fn cmp(&self, other: &Self) -> cmp::Ordering {
431        (self.inner as *const I).cmp(&(other.inner as *const I))
432    }
433}
434
435impl<'a, O, I> Hash for BoxOwned<'a, O, &'a mut I, ByAddress>
436where
437    O: ?Sized,
438    I: ?Sized,
439{
440    fn hash<H>(&self, state: &mut H)
441    where
442        H: Hasher,
443    {
444        ptr::hash(self.inner as *const I, state);
445    }
446}
447
448impl<'a, O, I> PartialEq<Self> for BoxOwned<'a, O, &'a I, ByAddress>
449where
450    O: ?Sized,
451    I: ?Sized,
452{
453    fn eq(&self, other: &Self) -> bool {
454        ptr::eq(self.inner as *const I, other.inner as *const I)
455    }
456}
457
458impl<'a, O, I> Eq for BoxOwned<'a, O, &'a I, ByAddress>
459where
460    O: ?Sized,
461    I: ?Sized,
462{
463}
464
465impl<'a, O, I> PartialOrd<Self> for BoxOwned<'a, O, &'a I, ByAddress>
466where
467    O: ?Sized,
468    I: ?Sized,
469{
470    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
471        (self.inner as *const I).partial_cmp(&(other.inner as *const I))
472    }
473}
474
475impl<'a, O, I> Ord for BoxOwned<'a, O, &'a I, ByAddress>
476where
477    O: ?Sized,
478    I: ?Sized,
479{
480    fn cmp(&self, other: &Self) -> cmp::Ordering {
481        (self.inner as *const I).cmp(&(other.inner as *const I))
482    }
483}
484
485impl<'a, O, I> Hash for BoxOwned<'a, O, &'a I, ByAddress>
486where
487    O: ?Sized,
488    I: ?Sized,
489{
490    fn hash<H>(&self, state: &mut H)
491    where
492        H: Hasher,
493    {
494        ptr::hash(self.inner as *const I, state);
495    }
496}
497
498impl<'a, O, I, E> AsRef<I> for BoxOwned<'a, O, I, E>
499where
500    O: ?Sized,
501    E: EqKind,
502{
503    fn as_ref(&self) -> &I {
504        self.deref()
505    }
506}
507
508impl<'a, O, I, E> AsMut<I> for BoxOwned<'a, O, I, E>
509where
510    O: ?Sized,
511    E: EqKind,
512{
513    fn as_mut(&mut self) -> &mut I {
514        self.deref_mut()
515    }
516}
517
518impl<'a, O, I, E> Borrow<I> for BoxOwned<'a, O, I, E>
519where
520    O: ?Sized,
521    E: EqKind,
522{
523    fn borrow(&self) -> &I {
524        self.deref()
525    }
526}
527
528impl<'a, O, I, E> Deref for BoxOwned<'a, O, I, E>
529where
530    O: ?Sized,
531    E: EqKind,
532{
533    type Target = I;
534
535    fn deref(&self) -> &Self::Target {
536        &self.inner
537    }
538}
539
540impl<'a, O, I, E> DerefMut for BoxOwned<'a, O, I, E>
541where
542    O: ?Sized,
543    E: EqKind,
544{
545    fn deref_mut(&mut self) -> &mut Self::Target {
546        &mut self.inner
547    }
548}
549
550impl<'a, O, E> From<Box<O>> for BoxOwned<'a, O, &'a mut O, E>
551where
552    O: ?Sized,
553    E: EqKind,
554{
555    fn from(mut owner: Box<O>) -> Self {
556        unsafe {
557            // re-borrow to obtain 'a lifetime
558            let inner = &mut *(owner.as_mut() as *mut O);
559
560            Self {
561                inner,
562                owner,
563                _phantom: PhantomData,
564            }
565        }
566    }
567}