intuicio_data/
managed.rs

1use crate::{
2    Finalize,
3    lifetime::{
4        Lifetime, LifetimeLazy, LifetimeRef, LifetimeRefMut, ValueReadAccess, ValueWriteAccess,
5    },
6    type_hash::TypeHash,
7};
8use std::{
9    alloc::{Layout, alloc, dealloc},
10    mem::MaybeUninit,
11};
12
13#[derive(Default)]
14pub struct Managed<T> {
15    lifetime: Lifetime,
16    data: T,
17}
18
19impl<T> Managed<T> {
20    pub fn new(data: T) -> Self {
21        Self {
22            lifetime: Default::default(),
23            data,
24        }
25    }
26
27    pub fn new_raw(data: T, lifetime: Lifetime) -> Self {
28        Self { lifetime, data }
29    }
30
31    pub fn into_inner(self) -> (Lifetime, T) {
32        (self.lifetime, self.data)
33    }
34
35    pub fn into_dynamic(self) -> Option<DynamicManaged> {
36        DynamicManaged::new(self.data).ok()
37    }
38
39    pub fn renew(mut self) -> Self {
40        self.lifetime = Lifetime::default();
41        self
42    }
43
44    pub fn lifetime(&self) -> &Lifetime {
45        &self.lifetime
46    }
47
48    pub fn read(&self) -> Option<ValueReadAccess<T>> {
49        self.lifetime.read(&self.data)
50    }
51
52    pub fn write(&mut self) -> Option<ValueWriteAccess<T>> {
53        self.lifetime.write(&mut self.data)
54    }
55
56    pub fn consume(self) -> Result<T, Self> {
57        if self.lifetime.state().is_in_use() {
58            Err(self)
59        } else {
60            Ok(self.data)
61        }
62    }
63
64    pub fn move_into_ref(self, mut target: ManagedRefMut<T>) -> Result<(), Self> {
65        *target.write().unwrap() = self.consume()?;
66        Ok(())
67    }
68
69    pub fn move_into_lazy(self, target: ManagedLazy<T>) -> Result<(), Self> {
70        *target.write().unwrap() = self.consume()?;
71        Ok(())
72    }
73
74    pub fn borrow(&self) -> Option<ManagedRef<T>> {
75        Some(ManagedRef::new(&self.data, self.lifetime.borrow()?))
76    }
77
78    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
79        Some(ManagedRefMut::new(
80            &mut self.data,
81            self.lifetime.borrow_mut()?,
82        ))
83    }
84
85    pub fn lazy(&mut self) -> ManagedLazy<T> {
86        ManagedLazy::new(&mut self.data, self.lifetime.lazy())
87    }
88
89    /// # Safety
90    pub unsafe fn map<U>(self, f: impl FnOnce(T) -> U) -> Managed<U> {
91        Managed {
92            lifetime: Default::default(),
93            data: f(self.data),
94        }
95    }
96
97    /// # Safety
98    pub unsafe fn try_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Managed<U>> {
99        f(self.data).map(|data| Managed {
100            lifetime: Default::default(),
101            data,
102        })
103    }
104
105    /// # Safety
106    pub unsafe fn as_ptr(&self) -> *const T {
107        &self.data as _
108    }
109
110    /// # Safety
111    pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
112        &mut self.data as _
113    }
114}
115
116impl<T> TryFrom<ManagedValue<T>> for Managed<T> {
117    type Error = ();
118
119    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
120        match value {
121            ManagedValue::Owned(value) => Ok(value),
122            _ => Err(()),
123        }
124    }
125}
126
127pub struct ManagedRef<T: ?Sized> {
128    lifetime: LifetimeRef,
129    data: *const T,
130}
131
132unsafe impl<T: ?Sized> Send for ManagedRef<T> where T: Send {}
133unsafe impl<T: ?Sized> Sync for ManagedRef<T> where T: Sync {}
134
135impl<T: ?Sized> ManagedRef<T> {
136    pub fn new(data: &T, lifetime: LifetimeRef) -> Self {
137        Self {
138            lifetime,
139            data: data as *const T,
140        }
141    }
142
143    /// # Safety
144    pub unsafe fn new_raw(data: *const T, lifetime: LifetimeRef) -> Option<Self> {
145        if data.is_null() {
146            None
147        } else {
148            Some(Self { lifetime, data })
149        }
150    }
151
152    pub fn make(data: &T) -> (Self, Lifetime) {
153        let result = Lifetime::default();
154        (Self::new(data, result.borrow().unwrap()), result)
155    }
156
157    /// # Safety
158    pub unsafe fn make_raw(data: *const T) -> Option<(Self, Lifetime)> {
159        let result = Lifetime::default();
160        Some((
161            unsafe { Self::new_raw(data, result.borrow().unwrap()) }?,
162            result,
163        ))
164    }
165
166    pub fn into_inner(self) -> (LifetimeRef, *const T) {
167        (self.lifetime, self.data)
168    }
169
170    pub fn into_dynamic(self) -> DynamicManagedRef {
171        unsafe {
172            DynamicManagedRef::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *const u8)
173                .unwrap()
174        }
175    }
176
177    pub fn lifetime(&self) -> &LifetimeRef {
178        &self.lifetime
179    }
180
181    pub fn borrow(&self) -> Option<ManagedRef<T>> {
182        Some(ManagedRef {
183            lifetime: self.lifetime.borrow()?,
184            data: self.data,
185        })
186    }
187
188    pub fn read(&self) -> Option<ValueReadAccess<T>> {
189        unsafe { self.lifetime.read_ptr(self.data) }
190    }
191
192    /// # Safety
193    pub unsafe fn map<U>(self, f: impl FnOnce(&T) -> &U) -> ManagedRef<U> {
194        unsafe {
195            let data = f(&*self.data);
196            ManagedRef {
197                lifetime: self.lifetime,
198                data: data as *const U,
199            }
200        }
201    }
202
203    /// # Safety
204    pub unsafe fn try_map<U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<ManagedRef<U>> {
205        unsafe {
206            f(&*self.data).map(|data| ManagedRef {
207                lifetime: self.lifetime,
208                data: data as *const U,
209            })
210        }
211    }
212
213    /// # Safety
214    pub unsafe fn as_ptr(&self) -> Option<*const T> {
215        if self.lifetime.exists() {
216            Some(self.data)
217        } else {
218            None
219        }
220    }
221}
222
223impl<T> TryFrom<ManagedValue<T>> for ManagedRef<T> {
224    type Error = ();
225
226    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
227        match value {
228            ManagedValue::Ref(value) => Ok(value),
229            _ => Err(()),
230        }
231    }
232}
233
234pub struct ManagedRefMut<T: ?Sized> {
235    lifetime: LifetimeRefMut,
236    data: *mut T,
237}
238
239unsafe impl<T: ?Sized> Send for ManagedRefMut<T> where T: Send {}
240unsafe impl<T: ?Sized> Sync for ManagedRefMut<T> where T: Sync {}
241
242impl<T: ?Sized> ManagedRefMut<T> {
243    pub fn new(data: &mut T, lifetime: LifetimeRefMut) -> Self {
244        Self {
245            lifetime,
246            data: data as *mut T,
247        }
248    }
249
250    /// # Safety
251    pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeRefMut) -> Option<Self> {
252        if data.is_null() {
253            None
254        } else {
255            Some(Self { lifetime, data })
256        }
257    }
258
259    pub fn make(data: &mut T) -> (Self, Lifetime) {
260        let result = Lifetime::default();
261        (Self::new(data, result.borrow_mut().unwrap()), result)
262    }
263
264    /// # Safety
265    pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
266        let result = Lifetime::default();
267        Some((
268            unsafe { Self::new_raw(data, result.borrow_mut().unwrap()) }?,
269            result,
270        ))
271    }
272
273    pub fn into_inner(self) -> (LifetimeRefMut, *mut T) {
274        (self.lifetime, self.data)
275    }
276
277    pub fn into_dynamic(self) -> DynamicManagedRefMut {
278        unsafe {
279            DynamicManagedRefMut::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
280                .unwrap()
281        }
282    }
283
284    pub fn lifetime(&self) -> &LifetimeRefMut {
285        &self.lifetime
286    }
287
288    pub fn borrow(&self) -> Option<ManagedRef<T>> {
289        Some(ManagedRef {
290            lifetime: self.lifetime.borrow()?,
291            data: self.data,
292        })
293    }
294
295    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
296        Some(ManagedRefMut {
297            lifetime: self.lifetime.borrow_mut()?,
298            data: self.data,
299        })
300    }
301
302    pub fn read(&self) -> Option<ValueReadAccess<T>> {
303        unsafe { self.lifetime.read_ptr(self.data) }
304    }
305
306    pub fn write(&mut self) -> Option<ValueWriteAccess<T>> {
307        unsafe { self.lifetime.write_ptr(self.data) }
308    }
309
310    /// # Safety
311    pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedRefMut<U> {
312        unsafe {
313            let data = f(&mut *self.data);
314            ManagedRefMut {
315                lifetime: self.lifetime,
316                data: data as *mut U,
317            }
318        }
319    }
320
321    /// # Safety
322    pub unsafe fn try_map<U>(
323        self,
324        f: impl FnOnce(&mut T) -> Option<&mut U>,
325    ) -> Option<ManagedRefMut<U>> {
326        unsafe {
327            f(&mut *self.data).map(|data| ManagedRefMut {
328                lifetime: self.lifetime,
329                data: data as *mut U,
330            })
331        }
332    }
333
334    /// # Safety
335    pub unsafe fn as_ptr(&self) -> Option<*const T> {
336        if self.lifetime.exists() {
337            Some(self.data)
338        } else {
339            None
340        }
341    }
342
343    /// # Safety
344    pub unsafe fn as_mut_ptr(&mut self) -> Option<*mut T> {
345        if self.lifetime.exists() {
346            Some(self.data)
347        } else {
348            None
349        }
350    }
351}
352
353impl<T> TryFrom<ManagedValue<T>> for ManagedRefMut<T> {
354    type Error = ();
355
356    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
357        match value {
358            ManagedValue::RefMut(value) => Ok(value),
359            _ => Err(()),
360        }
361    }
362}
363
364pub struct ManagedLazy<T: ?Sized> {
365    lifetime: LifetimeLazy,
366    data: *mut T,
367}
368
369unsafe impl<T: ?Sized> Send for ManagedLazy<T> where T: Send {}
370unsafe impl<T: ?Sized> Sync for ManagedLazy<T> where T: Sync {}
371
372impl<T: ?Sized> Clone for ManagedLazy<T> {
373    fn clone(&self) -> Self {
374        Self {
375            lifetime: self.lifetime.clone(),
376            data: self.data,
377        }
378    }
379}
380
381impl<T: ?Sized> ManagedLazy<T> {
382    pub fn new(data: &mut T, lifetime: LifetimeLazy) -> Self {
383        Self {
384            lifetime,
385            data: data as *mut T,
386        }
387    }
388
389    /// # Safety
390    pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeLazy) -> Option<Self> {
391        if data.is_null() {
392            None
393        } else {
394            Some(Self { lifetime, data })
395        }
396    }
397
398    pub fn make(data: &mut T) -> (Self, Lifetime) {
399        let result = Lifetime::default();
400        (Self::new(data, result.lazy()), result)
401    }
402
403    /// # Safety
404    pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
405        let result = Lifetime::default();
406        Some((unsafe { Self::new_raw(data, result.lazy()) }?, result))
407    }
408
409    pub fn into_inner(self) -> (LifetimeLazy, *mut T) {
410        (self.lifetime, self.data)
411    }
412
413    pub fn into_dynamic(self) -> DynamicManagedLazy {
414        unsafe {
415            DynamicManagedLazy::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
416                .unwrap()
417        }
418    }
419
420    pub fn lifetime(&self) -> &LifetimeLazy {
421        &self.lifetime
422    }
423
424    pub fn borrow(&self) -> Option<ManagedRef<T>> {
425        Some(ManagedRef {
426            lifetime: self.lifetime.borrow()?,
427            data: self.data,
428        })
429    }
430
431    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
432        Some(ManagedRefMut {
433            lifetime: self.lifetime.borrow_mut()?,
434            data: self.data,
435        })
436    }
437
438    pub fn read(&self) -> Option<ValueReadAccess<T>> {
439        unsafe { self.lifetime.read_ptr(self.data) }
440    }
441
442    pub fn write(&self) -> Option<ValueWriteAccess<T>> {
443        unsafe { self.lifetime.write_ptr(self.data) }
444    }
445
446    /// # Safety
447    pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedLazy<U> {
448        unsafe {
449            let data = f(&mut *self.data);
450            ManagedLazy {
451                lifetime: self.lifetime,
452                data: data as *mut U,
453            }
454        }
455    }
456
457    /// # Safety
458    pub unsafe fn try_map<U>(
459        self,
460        f: impl FnOnce(&mut T) -> Option<&mut U>,
461    ) -> Option<ManagedLazy<U>> {
462        unsafe {
463            f(&mut *self.data).map(|data| ManagedLazy {
464                lifetime: self.lifetime,
465                data: data as *mut U,
466            })
467        }
468    }
469
470    /// # Safety
471    pub unsafe fn as_ptr(&self) -> Option<*const T> {
472        if self.lifetime.exists() {
473            Some(self.data)
474        } else {
475            None
476        }
477    }
478
479    /// # Safety
480    pub unsafe fn as_mut_ptr(&self) -> Option<*mut T> {
481        if self.lifetime.exists() {
482            Some(self.data)
483        } else {
484            None
485        }
486    }
487}
488
489impl<T> TryFrom<ManagedValue<T>> for ManagedLazy<T> {
490    type Error = ();
491
492    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
493        match value {
494            ManagedValue::Lazy(value) => Ok(value),
495            _ => Err(()),
496        }
497    }
498}
499
500pub enum ManagedValue<T> {
501    Owned(Managed<T>),
502    Ref(ManagedRef<T>),
503    RefMut(ManagedRefMut<T>),
504    Lazy(ManagedLazy<T>),
505}
506
507impl<T> ManagedValue<T> {
508    pub fn as_owned(&self) -> Option<&Managed<T>> {
509        match self {
510            Self::Owned(value) => Some(value),
511            _ => None,
512        }
513    }
514
515    pub fn as_mut_owned(&mut self) -> Option<&mut Managed<T>> {
516        match self {
517            Self::Owned(value) => Some(value),
518            _ => None,
519        }
520    }
521
522    pub fn as_ref(&self) -> Option<&ManagedRef<T>> {
523        match self {
524            Self::Ref(value) => Some(value),
525            _ => None,
526        }
527    }
528
529    pub fn as_mut_ref(&mut self) -> Option<&mut ManagedRef<T>> {
530        match self {
531            Self::Ref(value) => Some(value),
532            _ => None,
533        }
534    }
535
536    pub fn as_ref_mut(&self) -> Option<&ManagedRefMut<T>> {
537        match self {
538            Self::RefMut(value) => Some(value),
539            _ => None,
540        }
541    }
542
543    pub fn as_mut_ref_mut(&mut self) -> Option<&mut ManagedRefMut<T>> {
544        match self {
545            Self::RefMut(value) => Some(value),
546            _ => None,
547        }
548    }
549
550    pub fn as_lazy(&self) -> Option<&ManagedLazy<T>> {
551        match self {
552            Self::Lazy(value) => Some(value),
553            _ => None,
554        }
555    }
556
557    pub fn as_mut_lazy(&mut self) -> Option<&mut ManagedLazy<T>> {
558        match self {
559            Self::Lazy(value) => Some(value),
560            _ => None,
561        }
562    }
563
564    pub fn read(&self) -> Option<ValueReadAccess<T>> {
565        match self {
566            Self::Owned(value) => value.read(),
567            Self::Ref(value) => value.read(),
568            Self::RefMut(value) => value.read(),
569            Self::Lazy(value) => value.read(),
570        }
571    }
572
573    pub fn write(&mut self) -> Option<ValueWriteAccess<T>> {
574        match self {
575            Self::Owned(value) => value.write(),
576            Self::RefMut(value) => value.write(),
577            Self::Lazy(value) => value.write(),
578            _ => None,
579        }
580    }
581
582    pub fn borrow(&self) -> Option<ManagedRef<T>> {
583        match self {
584            Self::Owned(value) => value.borrow(),
585            Self::Ref(value) => value.borrow(),
586            Self::RefMut(value) => value.borrow(),
587            _ => None,
588        }
589    }
590
591    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
592        match self {
593            Self::Owned(value) => value.borrow_mut(),
594            Self::RefMut(value) => value.borrow_mut(),
595            _ => None,
596        }
597    }
598
599    pub fn lazy(&mut self) -> Option<ManagedLazy<T>> {
600        match self {
601            Self::Owned(value) => Some(value.lazy()),
602            Self::Lazy(value) => Some(value.clone()),
603            _ => None,
604        }
605    }
606}
607
608impl<T> From<Managed<T>> for ManagedValue<T> {
609    fn from(value: Managed<T>) -> Self {
610        Self::Owned(value)
611    }
612}
613
614impl<T> From<ManagedRef<T>> for ManagedValue<T> {
615    fn from(value: ManagedRef<T>) -> Self {
616        Self::Ref(value)
617    }
618}
619
620impl<T> From<ManagedRefMut<T>> for ManagedValue<T> {
621    fn from(value: ManagedRefMut<T>) -> Self {
622        Self::RefMut(value)
623    }
624}
625
626impl<T> From<ManagedLazy<T>> for ManagedValue<T> {
627    fn from(value: ManagedLazy<T>) -> Self {
628        Self::Lazy(value)
629    }
630}
631
632pub struct DynamicManaged {
633    type_hash: TypeHash,
634    lifetime: Lifetime,
635    memory: *mut u8,
636    layout: Layout,
637    finalizer: unsafe fn(*mut ()),
638    drop: bool,
639}
640
641unsafe impl Send for DynamicManaged {}
642unsafe impl Sync for DynamicManaged {}
643
644impl Drop for DynamicManaged {
645    fn drop(&mut self) {
646        if self.drop {
647            unsafe {
648                let data_pointer = self.memory.cast::<()>();
649                (self.finalizer)(data_pointer);
650                dealloc(self.memory, self.layout);
651            }
652        }
653    }
654}
655
656impl DynamicManaged {
657    pub fn new<T: Finalize>(data: T) -> Result<Self, T> {
658        let layout = Layout::new::<T>().pad_to_align();
659        unsafe {
660            let memory = alloc(layout);
661            if memory.is_null() {
662                Err(data)
663            } else {
664                memory.cast::<T>().write(data);
665                Ok(Self {
666                    type_hash: TypeHash::of::<T>(),
667                    lifetime: Default::default(),
668                    memory,
669                    layout,
670                    finalizer: T::finalize_raw,
671                    drop: true,
672                })
673            }
674        }
675    }
676
677    pub fn new_raw(
678        type_hash: TypeHash,
679        lifetime: Lifetime,
680        memory: *mut u8,
681        layout: Layout,
682        finalizer: unsafe fn(*mut ()),
683    ) -> Option<Self> {
684        if memory.is_null() {
685            None
686        } else {
687            Some(Self {
688                type_hash,
689                lifetime,
690                memory,
691                layout,
692                finalizer,
693                drop: true,
694            })
695        }
696    }
697
698    /// # Safety
699    pub unsafe fn from_bytes(
700        type_hash: TypeHash,
701        lifetime: Lifetime,
702        bytes: Vec<u8>,
703        layout: Layout,
704        finalizer: unsafe fn(*mut ()),
705    ) -> Self {
706        let memory = unsafe { alloc(layout) };
707        unsafe { memory.copy_from(bytes.as_ptr(), bytes.len()) };
708        Self {
709            type_hash,
710            lifetime,
711            memory,
712            layout,
713            finalizer,
714            drop: true,
715        }
716    }
717
718    #[allow(clippy::type_complexity)]
719    pub fn into_inner(mut self) -> (TypeHash, Lifetime, *mut u8, Layout, unsafe fn(*mut ())) {
720        self.drop = false;
721        (
722            self.type_hash,
723            std::mem::take(&mut self.lifetime),
724            self.memory,
725            self.layout,
726            self.finalizer,
727        )
728    }
729
730    pub fn into_typed<T>(self) -> Result<Managed<T>, Self> {
731        Ok(Managed::new(self.consume()?))
732    }
733
734    pub fn renew(mut self) -> Self {
735        self.lifetime = Lifetime::default();
736        self
737    }
738
739    pub fn type_hash(&self) -> &TypeHash {
740        &self.type_hash
741    }
742
743    pub fn lifetime(&self) -> &Lifetime {
744        &self.lifetime
745    }
746
747    pub fn layout(&self) -> &Layout {
748        &self.layout
749    }
750
751    pub fn finalizer(&self) -> unsafe fn(*mut ()) {
752        self.finalizer
753    }
754
755    /// # Safety
756    pub unsafe fn memory(&self) -> &[u8] {
757        unsafe { std::slice::from_raw_parts(self.memory, self.layout.size()) }
758    }
759
760    /// # Safety
761    pub unsafe fn memory_mut(&mut self) -> &mut [u8] {
762        unsafe { std::slice::from_raw_parts_mut(self.memory, self.layout.size()) }
763    }
764
765    pub fn is<T>(&self) -> bool {
766        self.type_hash == TypeHash::of::<T>()
767    }
768
769    pub fn read<T>(&self) -> Option<ValueReadAccess<T>> {
770        if self.type_hash == TypeHash::of::<T>() {
771            unsafe { self.lifetime.read_ptr(self.memory.cast::<T>()) }
772        } else {
773            None
774        }
775    }
776
777    pub fn write<T>(&mut self) -> Option<ValueWriteAccess<T>> {
778        if self.type_hash == TypeHash::of::<T>() {
779            unsafe { self.lifetime.write_ptr(self.memory.cast::<T>()) }
780        } else {
781            None
782        }
783    }
784
785    pub fn consume<T>(mut self) -> Result<T, Self> {
786        if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
787            self.drop = false;
788            let mut result = MaybeUninit::<T>::uninit();
789            unsafe {
790                result.as_mut_ptr().copy_from(self.memory.cast::<T>(), 1);
791                dealloc(self.memory, self.layout);
792                Ok(result.assume_init())
793            }
794        } else {
795            Err(self)
796        }
797    }
798
799    pub fn move_into_ref(self, target: DynamicManagedRefMut) -> Result<(), Self> {
800        if self.type_hash == target.type_hash && self.memory != target.data {
801            let (_, _, memory, layout, _) = self.into_inner();
802            unsafe {
803                target.data.copy_from(memory, layout.size());
804                dealloc(memory, layout);
805            }
806            Ok(())
807        } else {
808            Err(self)
809        }
810    }
811
812    pub fn move_into_lazy(self, target: DynamicManagedLazy) -> Result<(), Self> {
813        if self.type_hash == target.type_hash && self.memory != target.data {
814            let (_, _, memory, layout, _) = self.into_inner();
815            unsafe {
816                target.data.copy_from(memory, layout.size());
817                dealloc(memory, layout);
818            }
819            Ok(())
820        } else {
821            Err(self)
822        }
823    }
824
825    pub fn borrow(&self) -> Option<DynamicManagedRef> {
826        unsafe { DynamicManagedRef::new_raw(self.type_hash, self.lifetime.borrow()?, self.memory) }
827    }
828
829    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
830        unsafe {
831            DynamicManagedRefMut::new_raw(self.type_hash, self.lifetime.borrow_mut()?, self.memory)
832        }
833    }
834
835    pub fn lazy(&self) -> DynamicManagedLazy {
836        unsafe {
837            DynamicManagedLazy::new_raw(self.type_hash, self.lifetime.lazy(), self.memory).unwrap()
838        }
839    }
840
841    /// # Safety
842    pub unsafe fn map<T, U: Finalize>(self, f: impl FnOnce(T) -> U) -> Option<Self> {
843        let data = self.consume::<T>().ok()?;
844        let data = f(data);
845        Self::new(data).ok()
846    }
847
848    /// # Safety
849    pub unsafe fn try_map<T, U: Finalize>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Self> {
850        let data = self.consume::<T>().ok()?;
851        let data = f(data)?;
852        Self::new(data).ok()
853    }
854
855    /// # Safety
856    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
857        if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
858            Some(self.memory.cast::<T>())
859        } else {
860            None
861        }
862    }
863
864    /// # Safety
865    pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
866        if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
867            Some(self.memory.cast::<T>())
868        } else {
869            None
870        }
871    }
872
873    /// # Safety
874    pub unsafe fn as_ptr_raw(&self) -> *const u8 {
875        self.memory
876    }
877
878    /// # Safety
879    pub unsafe fn as_mut_ptr_raw(&mut self) -> *mut u8 {
880        self.memory
881    }
882}
883
884impl TryFrom<DynamicManagedValue> for DynamicManaged {
885    type Error = ();
886
887    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
888        match value {
889            DynamicManagedValue::Owned(value) => Ok(value),
890            _ => Err(()),
891        }
892    }
893}
894
895pub struct DynamicManagedRef {
896    type_hash: TypeHash,
897    lifetime: LifetimeRef,
898    data: *const u8,
899}
900
901unsafe impl Send for DynamicManagedRef {}
902unsafe impl Sync for DynamicManagedRef {}
903
904impl DynamicManagedRef {
905    pub fn new<T: ?Sized>(data: &T, lifetime: LifetimeRef) -> Self {
906        Self {
907            type_hash: TypeHash::of::<T>(),
908            lifetime,
909            data: data as *const T as *const u8,
910        }
911    }
912
913    /// # Safety
914    pub unsafe fn new_raw(
915        type_hash: TypeHash,
916        lifetime: LifetimeRef,
917        data: *const u8,
918    ) -> Option<Self> {
919        if data.is_null() {
920            None
921        } else {
922            Some(Self {
923                type_hash,
924                lifetime,
925                data,
926            })
927        }
928    }
929
930    pub fn make<T: ?Sized>(data: &T) -> (Self, Lifetime) {
931        let result = Lifetime::default();
932        (Self::new(data, result.borrow().unwrap()), result)
933    }
934
935    pub fn into_inner(self) -> (TypeHash, LifetimeRef, *const u8) {
936        (self.type_hash, self.lifetime, self.data)
937    }
938
939    pub fn into_typed<T>(self) -> Result<ManagedRef<T>, Self> {
940        if self.type_hash == TypeHash::of::<T>() {
941            unsafe { Ok(ManagedRef::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
942        } else {
943            Err(self)
944        }
945    }
946
947    pub fn type_hash(&self) -> &TypeHash {
948        &self.type_hash
949    }
950
951    pub fn lifetime(&self) -> &LifetimeRef {
952        &self.lifetime
953    }
954
955    pub fn borrow(&self) -> Option<DynamicManagedRef> {
956        Some(DynamicManagedRef {
957            type_hash: self.type_hash,
958            lifetime: self.lifetime.borrow()?,
959            data: self.data,
960        })
961    }
962
963    pub fn is<T>(&self) -> bool {
964        self.type_hash == TypeHash::of::<T>()
965    }
966
967    pub fn read<T>(&self) -> Option<ValueReadAccess<T>> {
968        if self.type_hash == TypeHash::of::<T>() {
969            unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
970        } else {
971            None
972        }
973    }
974
975    /// # Safety
976    pub unsafe fn map<T, U>(self, f: impl FnOnce(&T) -> &U) -> Option<Self> {
977        if self.type_hash == TypeHash::of::<T>() {
978            unsafe {
979                let data = f(&*self.data.cast::<T>());
980                Some(Self {
981                    type_hash: TypeHash::of::<U>(),
982                    lifetime: self.lifetime,
983                    data: data as *const U as *const u8,
984                })
985            }
986        } else {
987            None
988        }
989    }
990
991    /// # Safety
992    pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<Self> {
993        if self.type_hash == TypeHash::of::<T>() {
994            unsafe {
995                let data = f(&*self.data.cast::<T>())?;
996                Some(Self {
997                    type_hash: TypeHash::of::<U>(),
998                    lifetime: self.lifetime,
999                    data: data as *const U as *const u8,
1000                })
1001            }
1002        } else {
1003            None
1004        }
1005    }
1006
1007    /// # Safety
1008    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1009        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1010            Some(self.data.cast::<T>())
1011        } else {
1012            None
1013        }
1014    }
1015
1016    /// # Safety
1017    pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1018        if self.lifetime.exists() {
1019            Some(self.data)
1020        } else {
1021            None
1022        }
1023    }
1024}
1025
1026impl TryFrom<DynamicManagedValue> for DynamicManagedRef {
1027    type Error = ();
1028
1029    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1030        match value {
1031            DynamicManagedValue::Ref(value) => Ok(value),
1032            _ => Err(()),
1033        }
1034    }
1035}
1036
1037pub struct DynamicManagedRefMut {
1038    type_hash: TypeHash,
1039    lifetime: LifetimeRefMut,
1040    data: *mut u8,
1041}
1042
1043unsafe impl Send for DynamicManagedRefMut {}
1044unsafe impl Sync for DynamicManagedRefMut {}
1045
1046impl DynamicManagedRefMut {
1047    pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeRefMut) -> Self {
1048        Self {
1049            type_hash: TypeHash::of::<T>(),
1050            lifetime,
1051            data: data as *mut T as *mut u8,
1052        }
1053    }
1054
1055    /// # Safety
1056    pub unsafe fn new_raw(
1057        type_hash: TypeHash,
1058        lifetime: LifetimeRefMut,
1059        data: *mut u8,
1060    ) -> Option<Self> {
1061        if data.is_null() {
1062            None
1063        } else {
1064            Some(Self {
1065                type_hash,
1066                lifetime,
1067                data,
1068            })
1069        }
1070    }
1071
1072    pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1073        let result = Lifetime::default();
1074        (Self::new(data, result.borrow_mut().unwrap()), result)
1075    }
1076
1077    pub fn into_inner(self) -> (TypeHash, LifetimeRefMut, *mut u8) {
1078        (self.type_hash, self.lifetime, self.data)
1079    }
1080
1081    pub fn into_typed<T>(self) -> Result<ManagedRefMut<T>, Self> {
1082        if self.type_hash == TypeHash::of::<T>() {
1083            unsafe { Ok(ManagedRefMut::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1084        } else {
1085            Err(self)
1086        }
1087    }
1088
1089    pub fn type_hash(&self) -> &TypeHash {
1090        &self.type_hash
1091    }
1092
1093    pub fn lifetime(&self) -> &LifetimeRefMut {
1094        &self.lifetime
1095    }
1096
1097    pub fn borrow(&self) -> Option<DynamicManagedRef> {
1098        Some(DynamicManagedRef {
1099            type_hash: self.type_hash,
1100            lifetime: self.lifetime.borrow()?,
1101            data: self.data,
1102        })
1103    }
1104
1105    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1106        Some(DynamicManagedRefMut {
1107            type_hash: self.type_hash,
1108            lifetime: self.lifetime.borrow_mut()?,
1109            data: self.data,
1110        })
1111    }
1112
1113    pub fn is<T>(&self) -> bool {
1114        self.type_hash == TypeHash::of::<T>()
1115    }
1116
1117    pub fn read<T>(&self) -> Option<ValueReadAccess<T>> {
1118        if self.type_hash == TypeHash::of::<T>() {
1119            unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1120        } else {
1121            None
1122        }
1123    }
1124
1125    pub fn write<T>(&mut self) -> Option<ValueWriteAccess<T>> {
1126        if self.type_hash == TypeHash::of::<T>() {
1127            unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1128        } else {
1129            None
1130        }
1131    }
1132
1133    /// # Safety
1134    pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1135        if self.type_hash == TypeHash::of::<T>() {
1136            unsafe {
1137                let data = f(&mut *self.data.cast::<T>());
1138                Some(Self {
1139                    type_hash: TypeHash::of::<U>(),
1140                    lifetime: self.lifetime,
1141                    data: data as *mut U as *mut u8,
1142                })
1143            }
1144        } else {
1145            None
1146        }
1147    }
1148
1149    /// # Safety
1150    pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1151        if self.type_hash == TypeHash::of::<T>() {
1152            unsafe {
1153                let data = f(&mut *self.data.cast::<T>())?;
1154                Some(Self {
1155                    type_hash: TypeHash::of::<U>(),
1156                    lifetime: self.lifetime,
1157                    data: data as *mut U as *mut u8,
1158                })
1159            }
1160        } else {
1161            None
1162        }
1163    }
1164
1165    /// # Safety
1166    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1167        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1168            Some(self.data.cast::<T>())
1169        } else {
1170            None
1171        }
1172    }
1173
1174    /// # Safety
1175    pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1176        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1177            Some(self.data.cast::<T>())
1178        } else {
1179            None
1180        }
1181    }
1182
1183    /// # Safety
1184    pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1185        if self.lifetime.exists() {
1186            Some(self.data)
1187        } else {
1188            None
1189        }
1190    }
1191
1192    /// # Safety
1193    pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1194        if self.lifetime.exists() {
1195            Some(self.data)
1196        } else {
1197            None
1198        }
1199    }
1200}
1201
1202impl TryFrom<DynamicManagedValue> for DynamicManagedRefMut {
1203    type Error = ();
1204
1205    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1206        match value {
1207            DynamicManagedValue::RefMut(value) => Ok(value),
1208            _ => Err(()),
1209        }
1210    }
1211}
1212
1213pub struct DynamicManagedLazy {
1214    type_hash: TypeHash,
1215    lifetime: LifetimeLazy,
1216    data: *mut u8,
1217}
1218
1219unsafe impl Send for DynamicManagedLazy {}
1220unsafe impl Sync for DynamicManagedLazy {}
1221
1222impl Clone for DynamicManagedLazy {
1223    fn clone(&self) -> Self {
1224        Self {
1225            type_hash: self.type_hash,
1226            lifetime: self.lifetime.clone(),
1227            data: self.data,
1228        }
1229    }
1230}
1231
1232impl DynamicManagedLazy {
1233    pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeLazy) -> Self {
1234        Self {
1235            type_hash: TypeHash::of::<T>(),
1236            lifetime,
1237            data: data as *mut T as *mut u8,
1238        }
1239    }
1240
1241    /// # Safety
1242    pub unsafe fn new_raw(
1243        type_hash: TypeHash,
1244        lifetime: LifetimeLazy,
1245        data: *mut u8,
1246    ) -> Option<Self> {
1247        if data.is_null() {
1248            None
1249        } else {
1250            Some(Self {
1251                type_hash,
1252                lifetime,
1253                data,
1254            })
1255        }
1256    }
1257
1258    pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1259        let result = Lifetime::default();
1260        (Self::new(data, result.lazy()), result)
1261    }
1262
1263    pub fn into_inner(self) -> (TypeHash, LifetimeLazy, *mut u8) {
1264        (self.type_hash, self.lifetime, self.data)
1265    }
1266
1267    pub fn into_typed<T>(self) -> Result<ManagedLazy<T>, Self> {
1268        if self.type_hash == TypeHash::of::<T>() {
1269            unsafe { Ok(ManagedLazy::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1270        } else {
1271            Err(self)
1272        }
1273    }
1274
1275    pub fn type_hash(&self) -> &TypeHash {
1276        &self.type_hash
1277    }
1278
1279    pub fn lifetime(&self) -> &LifetimeLazy {
1280        &self.lifetime
1281    }
1282
1283    pub fn is<T>(&self) -> bool {
1284        self.type_hash == TypeHash::of::<T>()
1285    }
1286
1287    pub fn read<T>(&self) -> Option<ValueReadAccess<T>> {
1288        if self.type_hash == TypeHash::of::<T>() {
1289            unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1290        } else {
1291            None
1292        }
1293    }
1294
1295    pub fn write<T>(&self) -> Option<ValueWriteAccess<T>> {
1296        if self.type_hash == TypeHash::of::<T>() {
1297            unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1298        } else {
1299            None
1300        }
1301    }
1302
1303    pub fn borrow(&self) -> Option<DynamicManagedRef> {
1304        Some(DynamicManagedRef {
1305            type_hash: self.type_hash,
1306            lifetime: self.lifetime.borrow()?,
1307            data: self.data,
1308        })
1309    }
1310
1311    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1312        Some(DynamicManagedRefMut {
1313            type_hash: self.type_hash,
1314            lifetime: self.lifetime.borrow_mut()?,
1315            data: self.data,
1316        })
1317    }
1318
1319    /// # Safety
1320    pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1321        if self.type_hash == TypeHash::of::<T>() {
1322            unsafe {
1323                let data = f(&mut *self.data.cast::<T>());
1324                Some(Self {
1325                    type_hash: TypeHash::of::<U>(),
1326                    lifetime: self.lifetime,
1327                    data: data as *mut U as *mut u8,
1328                })
1329            }
1330        } else {
1331            None
1332        }
1333    }
1334
1335    /// # Safety
1336    pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1337        if self.type_hash == TypeHash::of::<T>() {
1338            unsafe {
1339                let data = f(&mut *self.data.cast::<T>())?;
1340                Some(Self {
1341                    type_hash: TypeHash::of::<U>(),
1342                    lifetime: self.lifetime,
1343                    data: data as *mut U as *mut u8,
1344                })
1345            }
1346        } else {
1347            None
1348        }
1349    }
1350
1351    /// # Safety
1352    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1353        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1354            Some(self.data.cast::<T>())
1355        } else {
1356            None
1357        }
1358    }
1359
1360    /// # Safety
1361    pub unsafe fn as_mut_ptr<T>(&self) -> Option<*mut T> {
1362        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1363            Some(self.data.cast::<T>())
1364        } else {
1365            None
1366        }
1367    }
1368
1369    /// # Safety
1370    pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1371        if self.lifetime.exists() {
1372            Some(self.data)
1373        } else {
1374            None
1375        }
1376    }
1377
1378    /// # Safety
1379    pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1380        if self.lifetime.exists() {
1381            Some(self.data)
1382        } else {
1383            None
1384        }
1385    }
1386}
1387
1388impl TryFrom<DynamicManagedValue> for DynamicManagedLazy {
1389    type Error = ();
1390
1391    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1392        match value {
1393            DynamicManagedValue::Lazy(value) => Ok(value),
1394            _ => Err(()),
1395        }
1396    }
1397}
1398
1399pub enum DynamicManagedValue {
1400    Owned(DynamicManaged),
1401    Ref(DynamicManagedRef),
1402    RefMut(DynamicManagedRefMut),
1403    Lazy(DynamicManagedLazy),
1404}
1405
1406impl DynamicManagedValue {
1407    pub fn as_owned(&self) -> Option<&DynamicManaged> {
1408        match self {
1409            Self::Owned(value) => Some(value),
1410            _ => None,
1411        }
1412    }
1413
1414    pub fn as_mut_owned(&mut self) -> Option<&mut DynamicManaged> {
1415        match self {
1416            Self::Owned(value) => Some(value),
1417            _ => None,
1418        }
1419    }
1420
1421    pub fn as_ref(&self) -> Option<&DynamicManagedRef> {
1422        match self {
1423            Self::Ref(value) => Some(value),
1424            _ => None,
1425        }
1426    }
1427
1428    pub fn as_mut_ref(&mut self) -> Option<&mut DynamicManagedRef> {
1429        match self {
1430            Self::Ref(value) => Some(value),
1431            _ => None,
1432        }
1433    }
1434
1435    pub fn as_ref_mut(&self) -> Option<&DynamicManagedRefMut> {
1436        match self {
1437            Self::RefMut(value) => Some(value),
1438            _ => None,
1439        }
1440    }
1441
1442    pub fn as_mut_ref_mut(&mut self) -> Option<&mut DynamicManagedRefMut> {
1443        match self {
1444            Self::RefMut(value) => Some(value),
1445            _ => None,
1446        }
1447    }
1448
1449    pub fn as_lazy(&self) -> Option<&DynamicManagedLazy> {
1450        match self {
1451            Self::Lazy(value) => Some(value),
1452            _ => None,
1453        }
1454    }
1455
1456    pub fn as_mut_lazy(&mut self) -> Option<&mut DynamicManagedLazy> {
1457        match self {
1458            Self::Lazy(value) => Some(value),
1459            _ => None,
1460        }
1461    }
1462
1463    pub fn read<T>(&self) -> Option<ValueReadAccess<T>> {
1464        match self {
1465            Self::Owned(value) => value.read::<T>(),
1466            Self::Ref(value) => value.read::<T>(),
1467            Self::RefMut(value) => value.read::<T>(),
1468            Self::Lazy(value) => value.read::<T>(),
1469        }
1470    }
1471
1472    pub fn write<T>(&mut self) -> Option<ValueWriteAccess<T>> {
1473        match self {
1474            Self::Owned(value) => value.write::<T>(),
1475            Self::RefMut(value) => value.write::<T>(),
1476            Self::Lazy(value) => value.write::<T>(),
1477            _ => None,
1478        }
1479    }
1480
1481    pub fn borrow(&self) -> Option<DynamicManagedRef> {
1482        match self {
1483            Self::Owned(value) => value.borrow(),
1484            Self::Ref(value) => value.borrow(),
1485            Self::RefMut(value) => value.borrow(),
1486            _ => None,
1487        }
1488    }
1489
1490    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1491        match self {
1492            Self::Owned(value) => value.borrow_mut(),
1493            Self::RefMut(value) => value.borrow_mut(),
1494            _ => None,
1495        }
1496    }
1497
1498    pub fn lazy(&self) -> Option<DynamicManagedLazy> {
1499        match self {
1500            Self::Owned(value) => Some(value.lazy()),
1501            Self::Lazy(value) => Some(value.clone()),
1502            _ => None,
1503        }
1504    }
1505}
1506
1507impl From<DynamicManaged> for DynamicManagedValue {
1508    fn from(value: DynamicManaged) -> Self {
1509        Self::Owned(value)
1510    }
1511}
1512
1513impl From<DynamicManagedRef> for DynamicManagedValue {
1514    fn from(value: DynamicManagedRef) -> Self {
1515        Self::Ref(value)
1516    }
1517}
1518
1519impl From<DynamicManagedRefMut> for DynamicManagedValue {
1520    fn from(value: DynamicManagedRefMut) -> Self {
1521        Self::RefMut(value)
1522    }
1523}
1524
1525impl From<DynamicManagedLazy> for DynamicManagedValue {
1526    fn from(value: DynamicManagedLazy) -> Self {
1527        Self::Lazy(value)
1528    }
1529}
1530
1531#[cfg(test)]
1532mod tests {
1533    use super::*;
1534    use std::any::Any;
1535
1536    fn is_async<T: Send + Sync + ?Sized>() {}
1537
1538    #[test]
1539    fn test_managed() {
1540        is_async::<Managed<()>>();
1541        is_async::<ManagedRef<()>>();
1542        is_async::<ManagedRefMut<()>>();
1543        is_async::<ManagedLazy<()>>();
1544
1545        let mut value = Managed::new(42);
1546        let mut value_ref = value.borrow_mut().unwrap();
1547        assert!(value_ref.write().is_some());
1548        let mut value_ref2 = value_ref.borrow_mut().unwrap();
1549        assert!(value_ref.write().is_some());
1550        assert!(value_ref2.write().is_some());
1551        drop(value_ref);
1552        let value_ref = value.borrow().unwrap();
1553        assert!(value.borrow().is_some());
1554        assert!(value.borrow_mut().is_none());
1555        drop(value_ref);
1556        assert!(value.borrow().is_some());
1557        assert!(value.borrow_mut().is_some());
1558        *value.write().unwrap() = 40;
1559        assert_eq!(*value.read().unwrap(), 40);
1560        *value.borrow_mut().unwrap().write().unwrap() = 2;
1561        assert_eq!(*value.read().unwrap(), 2);
1562        let value_ref = value.borrow().unwrap();
1563        let value_ref2 = value_ref.borrow().unwrap();
1564        drop(value_ref);
1565        assert!(value_ref2.read().is_some());
1566        let value_ref = value.borrow().unwrap();
1567        let value_lazy = value.lazy();
1568        assert_eq!(*value_lazy.read().unwrap(), 2);
1569        *value_lazy.write().unwrap() = 42;
1570        assert_eq!(*value_lazy.read().unwrap(), 42);
1571        drop(value);
1572        assert!(value_ref.read().is_none());
1573        assert!(value_ref2.read().is_none());
1574        assert!(value_lazy.read().is_none());
1575    }
1576
1577    #[test]
1578    fn test_dynamic_managed() {
1579        is_async::<DynamicManaged>();
1580        is_async::<DynamicManagedRef>();
1581        is_async::<DynamicManagedRefMut>();
1582        is_async::<DynamicManagedLazy>();
1583
1584        let mut value = DynamicManaged::new(42).unwrap();
1585        let mut value_ref = value.borrow_mut().unwrap();
1586        assert!(value_ref.write::<i32>().is_some());
1587        let mut value_ref2 = value_ref.borrow_mut().unwrap();
1588        assert!(value_ref.write::<i32>().is_some());
1589        assert!(value_ref2.write::<i32>().is_some());
1590        drop(value_ref);
1591        let value_ref = value.borrow().unwrap();
1592        assert!(value.borrow().is_some());
1593        assert!(value.borrow_mut().is_none());
1594        drop(value_ref);
1595        assert!(value.borrow().is_some());
1596        assert!(value.borrow_mut().is_some());
1597        *value.write::<i32>().unwrap() = 40;
1598        assert_eq!(*value.read::<i32>().unwrap(), 40);
1599        *value.borrow_mut().unwrap().write::<i32>().unwrap() = 2;
1600        assert_eq!(*value.read::<i32>().unwrap(), 2);
1601        let value_ref = value.borrow().unwrap();
1602        let value_ref2 = value_ref.borrow().unwrap();
1603        drop(value_ref);
1604        assert!(value_ref2.read::<i32>().is_some());
1605        let value_ref = value.borrow().unwrap();
1606        let value_lazy = value.lazy();
1607        assert_eq!(*value_lazy.read::<i32>().unwrap(), 2);
1608        *value_lazy.write::<i32>().unwrap() = 42;
1609        assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1610        drop(value);
1611        assert!(value_ref.read::<i32>().is_none());
1612        assert!(value_ref2.read::<i32>().is_none());
1613        assert!(value_lazy.read::<i32>().is_none());
1614        let value = DynamicManaged::new("hello".to_owned()).unwrap();
1615        let value = value.consume::<String>().ok().unwrap();
1616        assert_eq!(value.as_str(), "hello");
1617    }
1618
1619    #[test]
1620    fn test_conversion() {
1621        let value = Managed::new(42);
1622        assert_eq!(*value.read().unwrap(), 42);
1623        let value = value.into_dynamic().unwrap();
1624        assert_eq!(*value.read::<i32>().unwrap(), 42);
1625        let mut value = value.into_typed::<i32>().ok().unwrap();
1626        assert_eq!(*value.read().unwrap(), 42);
1627
1628        let value_ref = value.borrow().unwrap();
1629        assert_eq!(*value.read().unwrap(), 42);
1630        let value_ref = value_ref.into_dynamic();
1631        assert_eq!(*value_ref.read::<i32>().unwrap(), 42);
1632        let value_ref = value_ref.into_typed::<i32>().ok().unwrap();
1633        assert_eq!(*value_ref.read().unwrap(), 42);
1634        drop(value_ref);
1635
1636        let value_ref_mut = value.borrow_mut().unwrap();
1637        assert_eq!(*value.read().unwrap(), 42);
1638        let value_ref_mut = value_ref_mut.into_dynamic();
1639        assert_eq!(*value_ref_mut.read::<i32>().unwrap(), 42);
1640        let value_ref_mut = value_ref_mut.into_typed::<i32>().ok().unwrap();
1641        assert_eq!(*value_ref_mut.read().unwrap(), 42);
1642
1643        let value_lazy = value.lazy();
1644        assert_eq!(*value.read().unwrap(), 42);
1645        let value_lazy = value_lazy.into_dynamic();
1646        assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1647        let value_lazy = value_lazy.into_typed::<i32>().ok().unwrap();
1648        assert_eq!(*value_lazy.read().unwrap(), 42);
1649    }
1650
1651    #[test]
1652    fn test_unsized() {
1653        let lifetime = Lifetime::default();
1654        let mut data = 42usize;
1655        {
1656            let foo = ManagedRef::<dyn Any>::new(&data, lifetime.borrow().unwrap());
1657            assert_eq!(
1658                *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1659                42usize
1660            );
1661        }
1662        {
1663            let mut foo = ManagedRefMut::<dyn Any>::new(&mut data, lifetime.borrow_mut().unwrap());
1664            *foo.write().unwrap().downcast_mut::<usize>().unwrap() = 100;
1665        }
1666        {
1667            let foo = ManagedLazy::<dyn Any>::new(&mut data, lifetime.lazy());
1668            assert_eq!(
1669                *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1670                100usize
1671            );
1672        }
1673
1674        let lifetime = Lifetime::default();
1675        let mut data = [0, 1, 2, 3];
1676        {
1677            let foo = ManagedRef::<[i32]>::new(&data, lifetime.borrow().unwrap());
1678            assert_eq!(*foo.read().unwrap(), [0, 1, 2, 3]);
1679        }
1680        {
1681            let mut foo = ManagedRefMut::<[i32]>::new(&mut data, lifetime.borrow_mut().unwrap());
1682            foo.write().unwrap().sort_by(|a, b| a.cmp(b).reverse());
1683        }
1684        {
1685            let foo = ManagedLazy::<[i32]>::new(&mut data, lifetime.lazy());
1686            assert_eq!(*foo.read().unwrap(), [3, 2, 1, 0]);
1687        }
1688    }
1689
1690    #[test]
1691    fn test_moves() {
1692        let mut value = Managed::new(42);
1693        assert_eq!(*value.read().unwrap(), 42);
1694        {
1695            let value_ref = value.borrow_mut().unwrap();
1696            Managed::new(1).move_into_ref(value_ref).ok().unwrap();
1697            assert_eq!(*value.read().unwrap(), 1);
1698        }
1699        {
1700            let value_lazy = value.lazy();
1701            Managed::new(2).move_into_lazy(value_lazy).ok().unwrap();
1702            assert_eq!(*value.read().unwrap(), 2);
1703        }
1704
1705        let mut value = DynamicManaged::new(42).unwrap();
1706        assert_eq!(*value.read::<i32>().unwrap(), 42);
1707        {
1708            let value_ref = value.borrow_mut().unwrap();
1709            DynamicManaged::new(1)
1710                .unwrap()
1711                .move_into_ref(value_ref)
1712                .ok()
1713                .unwrap();
1714            assert_eq!(*value.read::<i32>().unwrap(), 1);
1715        }
1716        {
1717            let value_lazy = value.lazy();
1718            DynamicManaged::new(2)
1719                .unwrap()
1720                .move_into_lazy(value_lazy)
1721                .ok()
1722                .unwrap();
1723            assert_eq!(*value.read::<i32>().unwrap(), 2);
1724        }
1725    }
1726
1727    #[test]
1728    fn test_move_invalidation() {
1729        let value = Managed::new(42);
1730        let value_ref = value.borrow().unwrap();
1731        assert_eq!(value.lifetime().tag(), value_ref.lifetime().tag());
1732        assert!(value_ref.lifetime().exists());
1733        let value = Box::new(value);
1734        assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
1735        assert!(!value_ref.lifetime().exists());
1736        let value = *value;
1737        assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
1738        assert!(!value_ref.lifetime().exists());
1739    }
1740}