1pub mod gc;
34pub mod value;
35
36use crate::{
37 Finalize, Finalizer,
38 lifetime::{
39 Lifetime, LifetimeLazy, LifetimeRef, LifetimeRefMut, ValueReadAccess, ValueWriteAccess,
40 },
41 managed::value::{DynamicManagedValue, ManagedValue},
42 non_zero_alloc, non_zero_dealloc,
43 type_hash::TypeHash,
44};
45use std::{alloc::Layout, mem::MaybeUninit};
46
47#[derive(Default)]
53pub struct Managed<T> {
54 lifetime: Lifetime,
55 data: T,
56}
57
58impl<T> Managed<T> {
59 pub fn new(data: T) -> Self {
61 Self {
62 lifetime: Default::default(),
63 data,
64 }
65 }
66
67 pub fn new_raw(data: T, lifetime: Lifetime) -> Self {
69 Self { lifetime, data }
70 }
71
72 pub fn into_inner(self) -> (Lifetime, T) {
74 (self.lifetime, self.data)
75 }
76
77 pub fn into_dynamic(self) -> Result<DynamicManaged, Self> {
82 match DynamicManaged::new(self.data) {
83 Ok(value) => Ok(value),
84 Err(data) => Err(Managed {
85 lifetime: self.lifetime,
86 data,
87 }),
88 }
89 }
90
91 pub fn renew(mut self) -> Self {
93 self.lifetime = Lifetime::default();
94 self
95 }
96
97 pub fn lifetime(&self) -> &Lifetime {
99 &self.lifetime
100 }
101
102 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
104 self.lifetime.read(&self.data)
105 }
106
107 pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
109 self.lifetime.write(&mut self.data)
110 }
111
112 pub fn consume(self) -> Result<T, Self> {
115 if self.lifetime.state().is_in_use() {
116 Err(self)
117 } else {
118 Ok(self.data)
119 }
120 }
121
122 pub fn move_into_ref(self, mut target: ManagedRefMut<T>) -> Result<(), Self> {
128 *target.write().unwrap() = self.consume()?;
129 Ok(())
130 }
131
132 pub fn move_into_lazy(self, target: ManagedLazy<T>) -> Result<(), Self> {
138 *target.write().unwrap() = self.consume()?;
139 Ok(())
140 }
141
142 pub fn borrow(&self) -> Option<ManagedRef<T>> {
144 Some(ManagedRef::new(&self.data, self.lifetime.borrow()?))
145 }
146
147 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
149 Some(ManagedRefMut::new(
150 &mut self.data,
151 self.lifetime.borrow_mut()?,
152 ))
153 }
154
155 pub fn lazy(&mut self) -> ManagedLazy<T> {
157 ManagedLazy::new(&mut self.data, self.lifetime.lazy())
158 }
159
160 pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
167 unsafe {
168 ManagedLazy::new_raw(&self.data as *const T as *mut T, self.lifetime.lazy()).unwrap()
169 }
170 }
171
172 pub unsafe fn map<U>(self, f: impl FnOnce(T) -> U) -> Managed<U> {
179 Managed {
180 lifetime: Default::default(),
181 data: f(self.data),
182 }
183 }
184
185 pub unsafe fn try_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Managed<U>> {
191 f(self.data).map(|data| Managed {
192 lifetime: Default::default(),
193 data,
194 })
195 }
196
197 pub unsafe fn as_ptr(&self) -> *const T {
204 &self.data as _
205 }
206
207 pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
214 &mut self.data as _
215 }
216}
217
218pub struct ManagedRef<T: ?Sized> {
223 lifetime: LifetimeRef,
224 data: *const T,
225}
226
227unsafe impl<T: ?Sized> Send for ManagedRef<T> where T: Send {}
228unsafe impl<T: ?Sized> Sync for ManagedRef<T> where T: Sync {}
229
230impl<T: ?Sized> ManagedRef<T> {
231 pub fn new(data: &T, lifetime: LifetimeRef) -> Self {
233 Self {
234 lifetime,
235 data: data as *const T,
236 }
237 }
238
239 pub unsafe fn new_raw(data: *const T, lifetime: LifetimeRef) -> Option<Self> {
246 if data.is_null() {
247 None
248 } else {
249 Some(Self { lifetime, data })
250 }
251 }
252
253 pub fn make(data: &T) -> (Self, Lifetime) {
259 let result = Lifetime::default();
260 (Self::new(data, result.borrow().unwrap()), result)
261 }
262
263 pub unsafe fn make_raw(data: *const T) -> Option<(Self, Lifetime)> {
269 let result = Lifetime::default();
270 Some((
271 unsafe { Self::new_raw(data, result.borrow().unwrap()) }?,
272 result,
273 ))
274 }
275
276 pub fn into_inner(self) -> (LifetimeRef, *const T) {
278 (self.lifetime, self.data)
279 }
280
281 pub fn into_dynamic(self) -> DynamicManagedRef {
283 unsafe {
284 DynamicManagedRef::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *const u8)
285 .unwrap()
286 }
287 }
288
289 pub fn lifetime(&self) -> &LifetimeRef {
291 &self.lifetime
292 }
293
294 pub fn borrow(&self) -> Option<ManagedRef<T>> {
296 Some(ManagedRef {
297 lifetime: self.lifetime.borrow()?,
298 data: self.data,
299 })
300 }
301
302 pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
309 ManagedLazy {
310 lifetime: self.lifetime.lazy(),
311 data: self.data as *mut T,
312 }
313 }
314
315 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
318 unsafe { self.lifetime.read_ptr(self.data) }
319 }
320
321 pub unsafe fn map<U>(self, f: impl FnOnce(&T) -> &U) -> ManagedRef<U> {
328 unsafe {
329 let data = f(&*self.data);
330 ManagedRef {
331 lifetime: self.lifetime,
332 data: data as *const U,
333 }
334 }
335 }
336
337 pub unsafe fn try_map<U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<ManagedRef<U>> {
343 unsafe {
344 f(&*self.data).map(|data| ManagedRef {
345 lifetime: self.lifetime,
346 data: data as *const U,
347 })
348 }
349 }
350
351 pub unsafe fn as_ptr(&self) -> Option<*const T> {
357 if self.lifetime.exists() {
358 Some(self.data)
359 } else {
360 None
361 }
362 }
363}
364
365impl<T> TryFrom<ManagedValue<T>> for ManagedRef<T> {
366 type Error = ();
367
368 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
369 match value {
370 ManagedValue::Ref(value) => Ok(value),
371 _ => Err(()),
372 }
373 }
374}
375
376pub struct ManagedRefMut<T: ?Sized> {
380 lifetime: LifetimeRefMut,
381 data: *mut T,
382}
383
384unsafe impl<T: ?Sized> Send for ManagedRefMut<T> where T: Send {}
385unsafe impl<T: ?Sized> Sync for ManagedRefMut<T> where T: Sync {}
386
387impl<T: ?Sized> ManagedRefMut<T> {
388 pub fn new(data: &mut T, lifetime: LifetimeRefMut) -> Self {
390 Self {
391 lifetime,
392 data: data as *mut T,
393 }
394 }
395
396 pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeRefMut) -> Option<Self> {
404 if data.is_null() {
405 None
406 } else {
407 Some(Self { lifetime, data })
408 }
409 }
410
411 pub fn make(data: &mut T) -> (Self, Lifetime) {
417 let result = Lifetime::default();
418 (Self::new(data, result.borrow_mut().unwrap()), result)
419 }
420
421 pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
428 let result = Lifetime::default();
429 Some((
430 unsafe { Self::new_raw(data, result.borrow_mut().unwrap()) }?,
431 result,
432 ))
433 }
434
435 pub fn into_inner(self) -> (LifetimeRefMut, *mut T) {
437 (self.lifetime, self.data)
438 }
439
440 pub fn into_dynamic(self) -> DynamicManagedRefMut {
442 unsafe {
443 DynamicManagedRefMut::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
444 .unwrap()
445 }
446 }
447
448 pub fn lifetime(&self) -> &LifetimeRefMut {
450 &self.lifetime
451 }
452
453 pub fn borrow(&self) -> Option<ManagedRef<T>> {
455 Some(ManagedRef {
456 lifetime: self.lifetime.borrow()?,
457 data: self.data,
458 })
459 }
460
461 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
463 Some(ManagedRefMut {
464 lifetime: self.lifetime.borrow_mut()?,
465 data: self.data,
466 })
467 }
468
469 pub fn lazy(&self) -> ManagedLazy<T> {
471 ManagedLazy {
472 lifetime: self.lifetime.lazy(),
473 data: self.data,
474 }
475 }
476
477 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
480 unsafe { self.lifetime.read_ptr(self.data) }
481 }
482
483 pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
486 unsafe { self.lifetime.write_ptr(self.data) }
487 }
488
489 pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedRefMut<U> {
496 unsafe {
497 let data = f(&mut *self.data);
498 ManagedRefMut {
499 lifetime: self.lifetime,
500 data: data as *mut U,
501 }
502 }
503 }
504
505 pub unsafe fn try_map<U>(
511 self,
512 f: impl FnOnce(&mut T) -> Option<&mut U>,
513 ) -> Option<ManagedRefMut<U>> {
514 unsafe {
515 f(&mut *self.data).map(|data| ManagedRefMut {
516 lifetime: self.lifetime,
517 data: data as *mut U,
518 })
519 }
520 }
521
522 pub unsafe fn as_ptr(&self) -> Option<*const T> {
528 if self.lifetime.exists() {
529 Some(self.data)
530 } else {
531 None
532 }
533 }
534
535 pub unsafe fn as_mut_ptr(&mut self) -> Option<*mut T> {
542 if self.lifetime.exists() {
543 Some(self.data)
544 } else {
545 None
546 }
547 }
548}
549
550impl<T> TryFrom<ManagedValue<T>> for ManagedRefMut<T> {
551 type Error = ();
552
553 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
554 match value {
555 ManagedValue::RefMut(value) => Ok(value),
556 _ => Err(()),
557 }
558 }
559}
560
561pub struct ManagedLazy<T: ?Sized> {
568 lifetime: LifetimeLazy,
569 data: *mut T,
570}
571
572unsafe impl<T: ?Sized> Send for ManagedLazy<T> where T: Send {}
573unsafe impl<T: ?Sized> Sync for ManagedLazy<T> where T: Sync {}
574
575impl<T: ?Sized> Clone for ManagedLazy<T> {
576 fn clone(&self) -> Self {
577 Self {
578 lifetime: self.lifetime.clone(),
579 data: self.data,
580 }
581 }
582}
583
584impl<T: ?Sized> ManagedLazy<T> {
585 pub fn new(data: &mut T, lifetime: LifetimeLazy) -> Self {
587 Self {
588 lifetime,
589 data: data as *mut T,
590 }
591 }
592
593 pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeLazy) -> Option<Self> {
600 if data.is_null() {
601 None
602 } else {
603 Some(Self { lifetime, data })
604 }
605 }
606
607 pub fn make(data: &mut T) -> (Self, Lifetime) {
613 let result = Lifetime::default();
614 (Self::new(data, result.lazy()), result)
615 }
616
617 pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
623 let result = Lifetime::default();
624 Some((unsafe { Self::new_raw(data, result.lazy()) }?, result))
625 }
626
627 pub fn into_inner(self) -> (LifetimeLazy, *mut T) {
629 (self.lifetime, self.data)
630 }
631
632 pub fn into_dynamic(self) -> DynamicManagedLazy {
634 unsafe {
635 DynamicManagedLazy::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
636 .unwrap()
637 }
638 }
639
640 pub fn lifetime(&self) -> &LifetimeLazy {
642 &self.lifetime
643 }
644
645 pub fn borrow(&self) -> Option<ManagedRef<T>> {
647 Some(ManagedRef {
648 lifetime: self.lifetime.borrow()?,
649 data: self.data,
650 })
651 }
652
653 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
655 Some(ManagedRefMut {
656 lifetime: self.lifetime.borrow_mut()?,
657 data: self.data,
658 })
659 }
660
661 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
664 unsafe { self.lifetime.read_ptr(self.data) }
665 }
666
667 pub fn write(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
672 unsafe { self.lifetime.write_ptr(self.data) }
673 }
674
675 pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedLazy<U> {
682 unsafe {
683 let data = f(&mut *self.data);
684 ManagedLazy {
685 lifetime: self.lifetime,
686 data: data as *mut U,
687 }
688 }
689 }
690
691 pub unsafe fn try_map<U>(
697 self,
698 f: impl FnOnce(&mut T) -> Option<&mut U>,
699 ) -> Option<ManagedLazy<U>> {
700 unsafe {
701 f(&mut *self.data).map(|data| ManagedLazy {
702 lifetime: self.lifetime,
703 data: data as *mut U,
704 })
705 }
706 }
707
708 pub unsafe fn as_ptr(&self) -> Option<*const T> {
714 if self.lifetime.exists() {
715 Some(self.data)
716 } else {
717 None
718 }
719 }
720
721 pub unsafe fn as_mut_ptr(&self) -> Option<*mut T> {
728 if self.lifetime.exists() {
729 Some(self.data)
730 } else {
731 None
732 }
733 }
734}
735
736impl<T> TryFrom<ManagedValue<T>> for ManagedLazy<T> {
737 type Error = ();
738
739 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
740 match value {
741 ManagedValue::Lazy(value) => Ok(value),
742 _ => Err(()),
743 }
744 }
745}
746
747pub struct DynamicManaged {
753 type_hash: TypeHash,
754 lifetime: Lifetime,
755 memory: *mut u8,
756 layout: Layout,
757 finalizer: Finalizer,
758 drop: bool,
759}
760
761unsafe impl Send for DynamicManaged {}
762unsafe impl Sync for DynamicManaged {}
763
764impl Drop for DynamicManaged {
765 fn drop(&mut self) {
766 if self.drop {
767 unsafe {
768 if self.memory.is_null() {
769 return;
770 }
771 let data_pointer = self.memory.cast::<()>();
772 self.finalizer.finalize(data_pointer);
773 non_zero_dealloc(self.memory, self.layout);
774 self.memory = std::ptr::null_mut();
775 }
776 }
777 }
778}
779
780impl DynamicManaged {
781 pub fn new<T: Finalize>(data: T) -> Result<Self, T> {
784 let layout = Layout::new::<T>().pad_to_align();
785 unsafe {
786 let memory = non_zero_alloc(layout);
787 if memory.is_null() {
788 Err(data)
789 } else {
790 memory.cast::<T>().write(data);
791 Ok(Self {
792 type_hash: TypeHash::of::<T>(),
793 lifetime: Default::default(),
794 memory,
795 layout,
796 finalizer: Finalizer::of::<T>(),
797 drop: true,
798 })
799 }
800 }
801 }
802
803 pub fn new_raw(
808 type_hash: TypeHash,
809 lifetime: Lifetime,
810 memory: *mut u8,
811 layout: Layout,
812 finalizer: impl Into<Finalizer>,
813 ) -> Option<Self> {
814 if memory.is_null() {
815 None
816 } else {
817 Some(Self {
818 type_hash,
819 lifetime,
820 memory,
821 layout,
822 finalizer: finalizer.into(),
823 drop: true,
824 })
825 }
826 }
827
828 pub fn new_uninitialized(
833 type_hash: TypeHash,
834 layout: Layout,
835 finalizer: impl Into<Finalizer>,
836 ) -> Self {
837 let layout = layout.pad_to_align();
838 let memory = unsafe { non_zero_alloc(layout) };
839 Self {
840 type_hash,
841 lifetime: Default::default(),
842 memory,
843 layout,
844 finalizer: finalizer.into(),
845 drop: true,
846 }
847 }
848
849 pub unsafe fn from_bytes(
857 type_hash: TypeHash,
858 lifetime: Lifetime,
859 bytes: Vec<u8>,
860 layout: Layout,
861 finalizer: impl Into<Finalizer>,
862 ) -> Self {
863 let layout = layout.pad_to_align();
864 let memory = unsafe { non_zero_alloc(layout) };
865 unsafe { memory.copy_from(bytes.as_ptr(), bytes.len()) };
866 Self {
867 type_hash,
868 lifetime,
869 memory,
870 layout,
871 finalizer: finalizer.into(),
872 drop: true,
873 }
874 }
875
876 #[allow(clippy::type_complexity)]
882 pub fn into_inner(mut self) -> (TypeHash, Lifetime, *mut u8, Layout, Finalizer) {
883 self.drop = false;
884 (
885 self.type_hash,
886 std::mem::take(&mut self.lifetime),
887 self.memory,
888 self.layout,
889 self.finalizer.clone(),
890 )
891 }
892
893 pub fn into_typed<T>(self) -> Result<Managed<T>, Self> {
896 Ok(Managed::new(self.consume()?))
897 }
898
899 pub fn renew(mut self) -> Self {
901 self.lifetime = Lifetime::default();
902 self
903 }
904
905 pub fn type_hash(&self) -> &TypeHash {
907 &self.type_hash
908 }
909
910 pub fn lifetime(&self) -> &Lifetime {
912 &self.lifetime
913 }
914
915 pub fn layout(&self) -> &Layout {
917 &self.layout
918 }
919
920 pub fn finalizer(&self) -> &Finalizer {
922 &self.finalizer
923 }
924
925 pub unsafe fn memory(&self) -> &[u8] {
932 unsafe { std::slice::from_raw_parts(self.memory, self.layout.size()) }
933 }
934
935 pub unsafe fn memory_mut(&mut self) -> &mut [u8] {
942 unsafe { std::slice::from_raw_parts_mut(self.memory, self.layout.size()) }
943 }
944
945 pub fn is<T>(&self) -> bool {
947 self.type_hash == TypeHash::of::<T>()
948 }
949
950 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
953 if self.type_hash == TypeHash::of::<T>() {
954 unsafe { self.lifetime.read_ptr(self.memory.cast::<T>()) }
955 } else {
956 None
957 }
958 }
959
960 pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
963 if self.type_hash == TypeHash::of::<T>() {
964 unsafe { self.lifetime.write_ptr(self.memory.cast::<T>()) }
965 } else {
966 None
967 }
968 }
969
970 pub fn consume<T>(mut self) -> Result<T, Self> {
974 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
975 if self.memory.is_null() {
976 return Err(self);
977 }
978 self.drop = false;
979 let mut result = MaybeUninit::<T>::uninit();
980 unsafe {
981 result.as_mut_ptr().copy_from(self.memory.cast::<T>(), 1);
982 non_zero_dealloc(self.memory, self.layout);
983 self.memory = std::ptr::null_mut();
984 Ok(result.assume_init())
985 }
986 } else {
987 Err(self)
988 }
989 }
990
991 pub fn move_into_ref(self, target: DynamicManagedRefMut) -> Result<(), Self> {
997 if self.type_hash == target.type_hash && self.memory != target.data {
998 if self.memory.is_null() {
999 return Err(self);
1000 }
1001 let (_, _, memory, layout, _) = self.into_inner();
1002 unsafe {
1003 target.data.copy_from(memory, layout.size());
1004 non_zero_dealloc(memory, layout);
1005 }
1006 Ok(())
1007 } else {
1008 Err(self)
1009 }
1010 }
1011
1012 pub fn move_into_lazy(self, target: DynamicManagedLazy) -> Result<(), Self> {
1018 if self.type_hash == target.type_hash && self.memory != target.data {
1019 if self.memory.is_null() {
1020 return Err(self);
1021 }
1022 let (_, _, memory, layout, _) = self.into_inner();
1023 unsafe {
1024 target.data.copy_from(memory, layout.size());
1025 non_zero_dealloc(memory, layout);
1026 }
1027 Ok(())
1028 } else {
1029 Err(self)
1030 }
1031 }
1032
1033 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1035 unsafe { DynamicManagedRef::new_raw(self.type_hash, self.lifetime.borrow()?, self.memory) }
1036 }
1037
1038 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1040 unsafe {
1041 DynamicManagedRefMut::new_raw(self.type_hash, self.lifetime.borrow_mut()?, self.memory)
1042 }
1043 }
1044
1045 pub fn lazy(&self) -> DynamicManagedLazy {
1047 unsafe {
1048 DynamicManagedLazy::new_raw(self.type_hash, self.lifetime.lazy(), self.memory).unwrap()
1049 }
1050 }
1051
1052 pub unsafe fn map<T, U: Finalize>(self, f: impl FnOnce(T) -> U) -> Option<Self> {
1059 let data = self.consume::<T>().ok()?;
1060 let data = f(data);
1061 Self::new(data).ok()
1062 }
1063
1064 pub unsafe fn try_map<T, U: Finalize>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Self> {
1071 let data = self.consume::<T>().ok()?;
1072 let data = f(data)?;
1073 Self::new(data).ok()
1074 }
1075
1076 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1082 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
1083 Some(self.memory.cast::<T>())
1084 } else {
1085 None
1086 }
1087 }
1088
1089 pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1095 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
1096 Some(self.memory.cast::<T>())
1097 } else {
1098 None
1099 }
1100 }
1101
1102 pub unsafe fn as_ptr_raw(&self) -> *const u8 {
1108 self.memory
1109 }
1110
1111 pub unsafe fn as_mut_ptr_raw(&mut self) -> *mut u8 {
1117 self.memory
1118 }
1119}
1120
1121impl TryFrom<DynamicManagedValue> for DynamicManaged {
1122 type Error = ();
1123
1124 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1125 match value {
1126 DynamicManagedValue::Owned(value) => Ok(value),
1127 _ => Err(()),
1128 }
1129 }
1130}
1131
1132pub struct DynamicManagedRef {
1136 type_hash: TypeHash,
1137 lifetime: LifetimeRef,
1138 data: *const u8,
1139}
1140
1141unsafe impl Send for DynamicManagedRef {}
1142unsafe impl Sync for DynamicManagedRef {}
1143
1144impl DynamicManagedRef {
1145 pub fn new<T: ?Sized>(data: &T, lifetime: LifetimeRef) -> Self {
1147 Self {
1148 type_hash: TypeHash::of::<T>(),
1149 lifetime,
1150 data: data as *const T as *const u8,
1151 }
1152 }
1153
1154 pub unsafe fn new_raw(
1162 type_hash: TypeHash,
1163 lifetime: LifetimeRef,
1164 data: *const u8,
1165 ) -> Option<Self> {
1166 if data.is_null() {
1167 None
1168 } else {
1169 Some(Self {
1170 type_hash,
1171 lifetime,
1172 data,
1173 })
1174 }
1175 }
1176
1177 pub fn make<T: ?Sized>(data: &T) -> (Self, Lifetime) {
1180 let result = Lifetime::default();
1181 (Self::new(data, result.borrow().unwrap()), result)
1182 }
1183
1184 pub fn into_inner(self) -> (TypeHash, LifetimeRef, *const u8) {
1186 (self.type_hash, self.lifetime, self.data)
1187 }
1188
1189 pub fn into_typed<T>(self) -> Result<ManagedRef<T>, Self> {
1191 if self.type_hash == TypeHash::of::<T>() {
1192 unsafe { Ok(ManagedRef::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1193 } else {
1194 Err(self)
1195 }
1196 }
1197
1198 pub fn type_hash(&self) -> &TypeHash {
1200 &self.type_hash
1201 }
1202
1203 pub fn lifetime(&self) -> &LifetimeRef {
1205 &self.lifetime
1206 }
1207
1208 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1210 Some(DynamicManagedRef {
1211 type_hash: self.type_hash,
1212 lifetime: self.lifetime.borrow()?,
1213 data: self.data,
1214 })
1215 }
1216
1217 pub unsafe fn lazy_immutable(&self) -> DynamicManagedLazy {
1224 DynamicManagedLazy {
1225 type_hash: self.type_hash,
1226 lifetime: self.lifetime.lazy(),
1227 data: self.data as *mut u8,
1228 }
1229 }
1230
1231 pub fn is<T>(&self) -> bool {
1233 self.type_hash == TypeHash::of::<T>()
1234 }
1235
1236 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1239 if self.type_hash == TypeHash::of::<T>() {
1240 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1241 } else {
1242 None
1243 }
1244 }
1245
1246 pub unsafe fn map<T, U>(self, f: impl FnOnce(&T) -> &U) -> Option<Self> {
1253 if self.type_hash == TypeHash::of::<T>() {
1254 unsafe {
1255 let data = f(&*self.data.cast::<T>());
1256 Some(Self {
1257 type_hash: TypeHash::of::<U>(),
1258 lifetime: self.lifetime,
1259 data: data as *const U as *const u8,
1260 })
1261 }
1262 } else {
1263 None
1264 }
1265 }
1266
1267 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<Self> {
1273 if self.type_hash == TypeHash::of::<T>() {
1274 unsafe {
1275 let data = f(&*self.data.cast::<T>())?;
1276 Some(Self {
1277 type_hash: TypeHash::of::<U>(),
1278 lifetime: self.lifetime,
1279 data: data as *const U as *const u8,
1280 })
1281 }
1282 } else {
1283 None
1284 }
1285 }
1286
1287 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1293 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1294 Some(self.data.cast::<T>())
1295 } else {
1296 None
1297 }
1298 }
1299
1300 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1306 if self.lifetime.exists() {
1307 Some(self.data)
1308 } else {
1309 None
1310 }
1311 }
1312}
1313
1314impl TryFrom<DynamicManagedValue> for DynamicManagedRef {
1315 type Error = ();
1316
1317 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1318 match value {
1319 DynamicManagedValue::Ref(value) => Ok(value),
1320 _ => Err(()),
1321 }
1322 }
1323}
1324
1325pub struct DynamicManagedRefMut {
1329 type_hash: TypeHash,
1330 lifetime: LifetimeRefMut,
1331 data: *mut u8,
1332}
1333
1334unsafe impl Send for DynamicManagedRefMut {}
1335unsafe impl Sync for DynamicManagedRefMut {}
1336
1337impl DynamicManagedRefMut {
1338 pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeRefMut) -> Self {
1340 Self {
1341 type_hash: TypeHash::of::<T>(),
1342 lifetime,
1343 data: data as *mut T as *mut u8,
1344 }
1345 }
1346
1347 pub unsafe fn new_raw(
1355 type_hash: TypeHash,
1356 lifetime: LifetimeRefMut,
1357 data: *mut u8,
1358 ) -> Option<Self> {
1359 if data.is_null() {
1360 None
1361 } else {
1362 Some(Self {
1363 type_hash,
1364 lifetime,
1365 data,
1366 })
1367 }
1368 }
1369
1370 pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1373 let result = Lifetime::default();
1374 (Self::new(data, result.borrow_mut().unwrap()), result)
1375 }
1376
1377 pub fn into_inner(self) -> (TypeHash, LifetimeRefMut, *mut u8) {
1379 (self.type_hash, self.lifetime, self.data)
1380 }
1381
1382 pub fn into_typed<T>(self) -> Result<ManagedRefMut<T>, Self> {
1384 if self.type_hash == TypeHash::of::<T>() {
1385 unsafe { Ok(ManagedRefMut::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1386 } else {
1387 Err(self)
1388 }
1389 }
1390
1391 pub fn type_hash(&self) -> &TypeHash {
1393 &self.type_hash
1394 }
1395
1396 pub fn lifetime(&self) -> &LifetimeRefMut {
1398 &self.lifetime
1399 }
1400
1401 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1403 Some(DynamicManagedRef {
1404 type_hash: self.type_hash,
1405 lifetime: self.lifetime.borrow()?,
1406 data: self.data,
1407 })
1408 }
1409
1410 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1412 Some(DynamicManagedRefMut {
1413 type_hash: self.type_hash,
1414 lifetime: self.lifetime.borrow_mut()?,
1415 data: self.data,
1416 })
1417 }
1418
1419 pub fn lazy(&self) -> DynamicManagedLazy {
1421 DynamicManagedLazy {
1422 type_hash: self.type_hash,
1423 lifetime: self.lifetime.lazy(),
1424 data: self.data,
1425 }
1426 }
1427
1428 pub fn is<T>(&self) -> bool {
1430 self.type_hash == TypeHash::of::<T>()
1431 }
1432
1433 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1436 if self.type_hash == TypeHash::of::<T>() {
1437 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1438 } else {
1439 None
1440 }
1441 }
1442
1443 pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
1446 if self.type_hash == TypeHash::of::<T>() {
1447 unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1448 } else {
1449 None
1450 }
1451 }
1452
1453 pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1460 if self.type_hash == TypeHash::of::<T>() {
1461 unsafe {
1462 let data = f(&mut *self.data.cast::<T>());
1463 Some(Self {
1464 type_hash: TypeHash::of::<U>(),
1465 lifetime: self.lifetime,
1466 data: data as *mut U as *mut u8,
1467 })
1468 }
1469 } else {
1470 None
1471 }
1472 }
1473
1474 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1480 if self.type_hash == TypeHash::of::<T>() {
1481 unsafe {
1482 let data = f(&mut *self.data.cast::<T>())?;
1483 Some(Self {
1484 type_hash: TypeHash::of::<U>(),
1485 lifetime: self.lifetime,
1486 data: data as *mut U as *mut u8,
1487 })
1488 }
1489 } else {
1490 None
1491 }
1492 }
1493
1494 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1500 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1501 Some(self.data.cast::<T>())
1502 } else {
1503 None
1504 }
1505 }
1506
1507 pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1513 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1514 Some(self.data.cast::<T>())
1515 } else {
1516 None
1517 }
1518 }
1519
1520 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1526 if self.lifetime.exists() {
1527 Some(self.data)
1528 } else {
1529 None
1530 }
1531 }
1532
1533 pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1539 if self.lifetime.exists() {
1540 Some(self.data)
1541 } else {
1542 None
1543 }
1544 }
1545}
1546
1547impl TryFrom<DynamicManagedValue> for DynamicManagedRefMut {
1548 type Error = ();
1549
1550 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1551 match value {
1552 DynamicManagedValue::RefMut(value) => Ok(value),
1553 _ => Err(()),
1554 }
1555 }
1556}
1557
1558pub struct DynamicManagedLazy {
1563 type_hash: TypeHash,
1564 lifetime: LifetimeLazy,
1565 data: *mut u8,
1566}
1567
1568unsafe impl Send for DynamicManagedLazy {}
1569unsafe impl Sync for DynamicManagedLazy {}
1570
1571impl Clone for DynamicManagedLazy {
1572 fn clone(&self) -> Self {
1573 Self {
1574 type_hash: self.type_hash,
1575 lifetime: self.lifetime.clone(),
1576 data: self.data,
1577 }
1578 }
1579}
1580
1581impl DynamicManagedLazy {
1582 pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeLazy) -> Self {
1584 Self {
1585 type_hash: TypeHash::of::<T>(),
1586 lifetime,
1587 data: data as *mut T as *mut u8,
1588 }
1589 }
1590
1591 pub unsafe fn new_raw(
1599 type_hash: TypeHash,
1600 lifetime: LifetimeLazy,
1601 data: *mut u8,
1602 ) -> Option<Self> {
1603 if data.is_null() {
1604 None
1605 } else {
1606 Some(Self {
1607 type_hash,
1608 lifetime,
1609 data,
1610 })
1611 }
1612 }
1613
1614 pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1617 let result = Lifetime::default();
1618 (Self::new(data, result.lazy()), result)
1619 }
1620
1621 pub fn into_inner(self) -> (TypeHash, LifetimeLazy, *mut u8) {
1623 (self.type_hash, self.lifetime, self.data)
1624 }
1625
1626 pub fn into_typed<T>(self) -> Result<ManagedLazy<T>, Self> {
1628 if self.type_hash == TypeHash::of::<T>() {
1629 unsafe { Ok(ManagedLazy::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1630 } else {
1631 Err(self)
1632 }
1633 }
1634
1635 pub fn type_hash(&self) -> &TypeHash {
1637 &self.type_hash
1638 }
1639
1640 pub fn lifetime(&self) -> &LifetimeLazy {
1642 &self.lifetime
1643 }
1644
1645 pub fn is<T>(&self) -> bool {
1647 self.type_hash == TypeHash::of::<T>()
1648 }
1649
1650 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1653 if self.type_hash == TypeHash::of::<T>() {
1654 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1655 } else {
1656 None
1657 }
1658 }
1659
1660 pub fn write<T>(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
1665 if self.type_hash == TypeHash::of::<T>() {
1666 unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1667 } else {
1668 None
1669 }
1670 }
1671
1672 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1674 Some(DynamicManagedRef {
1675 type_hash: self.type_hash,
1676 lifetime: self.lifetime.borrow()?,
1677 data: self.data,
1678 })
1679 }
1680
1681 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1683 Some(DynamicManagedRefMut {
1684 type_hash: self.type_hash,
1685 lifetime: self.lifetime.borrow_mut()?,
1686 data: self.data,
1687 })
1688 }
1689
1690 pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1697 if self.type_hash == TypeHash::of::<T>() {
1698 unsafe {
1699 let data = f(&mut *self.data.cast::<T>());
1700 Some(Self {
1701 type_hash: TypeHash::of::<U>(),
1702 lifetime: self.lifetime,
1703 data: data as *mut U as *mut u8,
1704 })
1705 }
1706 } else {
1707 None
1708 }
1709 }
1710
1711 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1717 if self.type_hash == TypeHash::of::<T>() {
1718 unsafe {
1719 let data = f(&mut *self.data.cast::<T>())?;
1720 Some(Self {
1721 type_hash: TypeHash::of::<U>(),
1722 lifetime: self.lifetime,
1723 data: data as *mut U as *mut u8,
1724 })
1725 }
1726 } else {
1727 None
1728 }
1729 }
1730
1731 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1737 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1738 Some(self.data.cast::<T>())
1739 } else {
1740 None
1741 }
1742 }
1743
1744 pub unsafe fn as_mut_ptr<T>(&self) -> Option<*mut T> {
1750 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1751 Some(self.data.cast::<T>())
1752 } else {
1753 None
1754 }
1755 }
1756
1757 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1763 if self.lifetime.exists() {
1764 Some(self.data)
1765 } else {
1766 None
1767 }
1768 }
1769
1770 pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1776 if self.lifetime.exists() {
1777 Some(self.data)
1778 } else {
1779 None
1780 }
1781 }
1782}
1783
1784impl TryFrom<DynamicManagedValue> for DynamicManagedLazy {
1785 type Error = ();
1786
1787 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1788 match value {
1789 DynamicManagedValue::Lazy(value) => Ok(value),
1790 _ => Err(()),
1791 }
1792 }
1793}
1794
1795#[cfg(test)]
1796mod tests {
1797 use super::*;
1798 use std::any::Any;
1799
1800 fn is_async<T: Send + Sync + ?Sized>() {}
1801
1802 #[test]
1803 fn test_managed() {
1804 is_async::<Managed<()>>();
1805 is_async::<ManagedRef<()>>();
1806 is_async::<ManagedRefMut<()>>();
1807 is_async::<ManagedLazy<()>>();
1808 is_async::<ManagedValue<()>>();
1809
1810 let mut value = Managed::new(42);
1811 let mut value_ref = value.borrow_mut().unwrap();
1812 assert!(value_ref.write().is_some());
1813 let mut value_ref2 = value_ref.borrow_mut().unwrap();
1814 assert!(value_ref.write().is_some());
1815 assert!(value_ref2.write().is_some());
1816 drop(value_ref);
1817 let value_ref = value.borrow().unwrap();
1818 assert!(value.borrow().is_some());
1819 assert!(value.borrow_mut().is_none());
1820 drop(value_ref);
1821 assert!(value.borrow().is_some());
1822 assert!(value.borrow_mut().is_some());
1823 *value.write().unwrap() = 40;
1824 assert_eq!(*value.read().unwrap(), 40);
1825 *value.borrow_mut().unwrap().write().unwrap() = 2;
1826 assert_eq!(*value.read().unwrap(), 2);
1827 let value_ref = value.borrow().unwrap();
1828 let value_ref2 = value_ref.borrow().unwrap();
1829 drop(value_ref);
1830 assert!(value_ref2.read().is_some());
1831 let value_ref = value.borrow().unwrap();
1832 let value_lazy = value.lazy();
1833 assert_eq!(*value_lazy.read().unwrap(), 2);
1834 *value_lazy.write().unwrap() = 42;
1835 assert_eq!(*value_lazy.read().unwrap(), 42);
1836 drop(value);
1837 assert!(value_ref.read().is_none());
1838 assert!(value_ref2.read().is_none());
1839 assert!(value_lazy.read().is_none());
1840 }
1841
1842 #[test]
1843 fn test_dynamic_managed() {
1844 is_async::<DynamicManaged>();
1845 is_async::<DynamicManagedRef>();
1846 is_async::<DynamicManagedRefMut>();
1847 is_async::<DynamicManagedLazy>();
1848 is_async::<DynamicManagedValue>();
1849
1850 let mut value = DynamicManaged::new(42).unwrap();
1851 let mut value_ref = value.borrow_mut().unwrap();
1852 assert!(value_ref.write::<i32>().is_some());
1853 let mut value_ref2 = value_ref.borrow_mut().unwrap();
1854 assert!(value_ref.write::<i32>().is_some());
1855 assert!(value_ref2.write::<i32>().is_some());
1856 drop(value_ref);
1857 let value_ref = value.borrow().unwrap();
1858 assert!(value.borrow().is_some());
1859 assert!(value.borrow_mut().is_none());
1860 drop(value_ref);
1861 assert!(value.borrow().is_some());
1862 assert!(value.borrow_mut().is_some());
1863 *value.write::<i32>().unwrap() = 40;
1864 assert_eq!(*value.read::<i32>().unwrap(), 40);
1865 *value.borrow_mut().unwrap().write::<i32>().unwrap() = 2;
1866 assert_eq!(*value.read::<i32>().unwrap(), 2);
1867 let value_ref = value.borrow().unwrap();
1868 let value_ref2 = value_ref.borrow().unwrap();
1869 drop(value_ref);
1870 assert!(value_ref2.read::<i32>().is_some());
1871 let value_ref = value.borrow().unwrap();
1872 let value_lazy = value.lazy();
1873 assert_eq!(*value_lazy.read::<i32>().unwrap(), 2);
1874 *value_lazy.write::<i32>().unwrap() = 42;
1875 assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1876 drop(value);
1877 assert!(value_ref.read::<i32>().is_none());
1878 assert!(value_ref2.read::<i32>().is_none());
1879 assert!(value_lazy.read::<i32>().is_none());
1880 let value = DynamicManaged::new("hello".to_owned()).unwrap();
1881 let value = value.consume::<String>().ok().unwrap();
1882 assert_eq!(value.as_str(), "hello");
1883 }
1884
1885 #[test]
1886 fn test_conversion() {
1887 let value = Managed::new(42);
1888 assert_eq!(*value.read().unwrap(), 42);
1889 let value = value.into_dynamic().ok().unwrap();
1890 assert_eq!(*value.read::<i32>().unwrap(), 42);
1891 let mut value = value.into_typed::<i32>().ok().unwrap();
1892 assert_eq!(*value.read().unwrap(), 42);
1893
1894 let value_ref = value.borrow().unwrap();
1895 assert_eq!(*value.read().unwrap(), 42);
1896 let value_ref = value_ref.into_dynamic();
1897 assert_eq!(*value_ref.read::<i32>().unwrap(), 42);
1898 let value_ref = value_ref.into_typed::<i32>().ok().unwrap();
1899 assert_eq!(*value_ref.read().unwrap(), 42);
1900 drop(value_ref);
1901
1902 let value_ref_mut = value.borrow_mut().unwrap();
1903 assert_eq!(*value.read().unwrap(), 42);
1904 let value_ref_mut = value_ref_mut.into_dynamic();
1905 assert_eq!(*value_ref_mut.read::<i32>().unwrap(), 42);
1906 let value_ref_mut = value_ref_mut.into_typed::<i32>().ok().unwrap();
1907 assert_eq!(*value_ref_mut.read().unwrap(), 42);
1908
1909 let value_lazy = value.lazy();
1910 assert_eq!(*value.read().unwrap(), 42);
1911 let value_lazy = value_lazy.into_dynamic();
1912 assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1913 let value_lazy = value_lazy.into_typed::<i32>().ok().unwrap();
1914 assert_eq!(*value_lazy.read().unwrap(), 42);
1915 }
1916
1917 #[test]
1918 fn test_unsized() {
1919 let lifetime = Lifetime::default();
1920 let mut data = 42usize;
1921 {
1922 let foo = ManagedRef::<dyn Any>::new(&data, lifetime.borrow().unwrap());
1923 assert_eq!(
1924 *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1925 42usize
1926 );
1927 }
1928 {
1929 let mut foo = ManagedRefMut::<dyn Any>::new(&mut data, lifetime.borrow_mut().unwrap());
1930 *foo.write().unwrap().downcast_mut::<usize>().unwrap() = 100;
1931 }
1932 {
1933 let foo = ManagedLazy::<dyn Any>::new(&mut data, lifetime.lazy());
1934 assert_eq!(
1935 *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1936 100usize
1937 );
1938 }
1939
1940 let lifetime = Lifetime::default();
1941 let mut data = [0, 1, 2, 3];
1942 {
1943 let foo = ManagedRef::<[i32]>::new(&data, lifetime.borrow().unwrap());
1944 assert_eq!(*foo.read().unwrap(), [0, 1, 2, 3]);
1945 }
1946 {
1947 let mut foo = ManagedRefMut::<[i32]>::new(&mut data, lifetime.borrow_mut().unwrap());
1948 foo.write().unwrap().sort_by(|a, b| a.cmp(b).reverse());
1949 }
1950 {
1951 let foo = ManagedLazy::<[i32]>::new(&mut data, lifetime.lazy());
1952 assert_eq!(*foo.read().unwrap(), [3, 2, 1, 0]);
1953 }
1954 }
1955
1956 #[test]
1957 fn test_moves() {
1958 let mut value = Managed::new(42);
1959 assert_eq!(*value.read().unwrap(), 42);
1960 {
1961 let value_ref = value.borrow_mut().unwrap();
1962 Managed::new(1).move_into_ref(value_ref).ok().unwrap();
1963 assert_eq!(*value.read().unwrap(), 1);
1964 }
1965 {
1966 let value_lazy = value.lazy();
1967 Managed::new(2).move_into_lazy(value_lazy).ok().unwrap();
1968 assert_eq!(*value.read().unwrap(), 2);
1969 }
1970
1971 let mut value = DynamicManaged::new(42).unwrap();
1972 assert_eq!(*value.read::<i32>().unwrap(), 42);
1973 {
1974 let value_ref = value.borrow_mut().unwrap();
1975 DynamicManaged::new(1)
1976 .unwrap()
1977 .move_into_ref(value_ref)
1978 .ok()
1979 .unwrap();
1980 assert_eq!(*value.read::<i32>().unwrap(), 1);
1981 }
1982 {
1983 let value_lazy = value.lazy();
1984 DynamicManaged::new(2)
1985 .unwrap()
1986 .move_into_lazy(value_lazy)
1987 .ok()
1988 .unwrap();
1989 assert_eq!(*value.read::<i32>().unwrap(), 2);
1990 }
1991 }
1992
1993 #[test]
1994 fn test_move_invalidation() {
1995 let value = Managed::new(42);
1996 let value_ref = value.borrow().unwrap();
1997 assert_eq!(value.lifetime().tag(), value_ref.lifetime().tag());
1998 assert!(value_ref.lifetime().exists());
1999 let value = Box::new(value);
2000 assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
2001 assert!(!value_ref.lifetime().exists());
2002 let value = *value;
2003 assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
2004 assert!(!value_ref.lifetime().exists());
2005 }
2006}