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, cell::UnsafeCell, mem::MaybeUninit};
46
47#[derive(Default)]
59pub struct Managed<T> {
60 lifetime: Lifetime,
61 data: UnsafeCell<T>,
62}
63
64unsafe impl<T> Sync for Managed<T> where T: Sync {}
69
70impl<T> Managed<T> {
71 pub fn new(data: T) -> Self {
73 Self {
74 lifetime: Default::default(),
75 data: UnsafeCell::new(data),
76 }
77 }
78
79 pub fn new_raw(data: T, lifetime: Lifetime) -> Self {
81 Self {
82 lifetime,
83 data: UnsafeCell::new(data),
84 }
85 }
86
87 pub fn into_inner(self) -> (Lifetime, T) {
89 (self.lifetime, self.data.into_inner())
90 }
91
92 pub fn into_dynamic(self) -> Result<DynamicManaged, Self> {
97 match DynamicManaged::new(self.data.into_inner()) {
98 Ok(value) => Ok(value),
99 Err(data) => Err(Managed {
100 lifetime: self.lifetime,
101 data: UnsafeCell::new(data),
102 }),
103 }
104 }
105
106 pub fn renew(mut self) -> Self {
108 self.lifetime = Lifetime::default();
109 self
110 }
111
112 pub fn lifetime(&self) -> &Lifetime {
114 &self.lifetime
115 }
116
117 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
119 unsafe { self.lifetime.read_ptr(self.data.get() as *const T) }
120 }
121
122 pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
124 unsafe { self.lifetime.write_ptr(self.data.get()) }
125 }
126
127 pub fn consume(self) -> Result<T, Self> {
130 if self.lifetime.state().is_in_use() {
131 Err(self)
132 } else {
133 Ok(self.data.into_inner())
134 }
135 }
136
137 pub fn move_into_ref(self, mut target: ManagedRefMut<T>) -> Result<(), Self> {
143 *target.write().unwrap() = self.consume()?;
144 Ok(())
145 }
146
147 pub fn move_into_lazy(self, target: ManagedLazy<T>) -> Result<(), Self> {
153 *target.write().unwrap() = self.consume()?;
154 Ok(())
155 }
156
157 pub fn borrow(&self) -> Option<ManagedRef<T>> {
159 Some(ManagedRef {
160 lifetime: self.lifetime.borrow()?,
161 data: self.data.get(),
162 })
163 }
164
165 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
167 Some(ManagedRefMut {
168 lifetime: self.lifetime.borrow_mut()?,
169 data: self.data.get(),
170 })
171 }
172
173 pub fn lazy(&mut self) -> ManagedLazy<T> {
175 ManagedLazy {
176 lifetime: self.lifetime.lazy(),
177 data: self.data.get(),
178 }
179 }
180
181 pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
188 ManagedLazy {
189 lifetime: self.lifetime.lazy(),
190 data: self.data.get(),
191 }
192 }
193
194 pub unsafe fn map<U>(self, f: impl FnOnce(T) -> U) -> Managed<U> {
201 Managed {
202 lifetime: Default::default(),
203 data: UnsafeCell::new(f(self.data.into_inner())),
204 }
205 }
206
207 pub unsafe fn try_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Managed<U>> {
213 f(self.data.into_inner()).map(|data| Managed {
214 lifetime: Default::default(),
215 data: UnsafeCell::new(data),
216 })
217 }
218
219 pub unsafe fn as_ptr(&self) -> *const T {
226 self.data.get() as *const T
227 }
228
229 pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
236 self.data.get()
237 }
238}
239
240pub struct ManagedRef<T: ?Sized> {
245 lifetime: LifetimeRef,
246 data: *const T,
247}
248
249unsafe impl<T: ?Sized> Send for ManagedRef<T> where T: Send {}
250unsafe impl<T: ?Sized> Sync for ManagedRef<T> where T: Sync {}
251
252impl<T: ?Sized> ManagedRef<T> {
253 pub fn new(data: &T, lifetime: LifetimeRef) -> Self {
255 Self {
256 lifetime,
257 data: data as *const T,
258 }
259 }
260
261 pub unsafe fn new_raw(data: *const T, lifetime: LifetimeRef) -> Option<Self> {
268 if data.is_null() {
269 None
270 } else {
271 Some(Self { lifetime, data })
272 }
273 }
274
275 pub fn make(data: &T) -> (Self, Lifetime) {
281 let result = Lifetime::default();
282 (Self::new(data, result.borrow().unwrap()), result)
283 }
284
285 pub unsafe fn make_raw(data: *const T) -> Option<(Self, Lifetime)> {
291 let result = Lifetime::default();
292 Some((
293 unsafe { Self::new_raw(data, result.borrow().unwrap()) }?,
294 result,
295 ))
296 }
297
298 pub fn into_inner(self) -> (LifetimeRef, *const T) {
300 (self.lifetime, self.data)
301 }
302
303 pub fn into_dynamic(self) -> DynamicManagedRef {
305 unsafe {
306 DynamicManagedRef::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *const u8)
307 .unwrap()
308 }
309 }
310
311 pub fn lifetime(&self) -> &LifetimeRef {
313 &self.lifetime
314 }
315
316 pub fn borrow(&self) -> Option<ManagedRef<T>> {
318 Some(ManagedRef {
319 lifetime: self.lifetime.borrow()?,
320 data: self.data,
321 })
322 }
323
324 pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
331 ManagedLazy {
332 lifetime: self.lifetime.lazy(),
333 data: self.data as *mut T,
334 }
335 }
336
337 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
340 unsafe { self.lifetime.read_ptr(self.data) }
341 }
342
343 pub unsafe fn map<U>(self, f: impl FnOnce(&T) -> &U) -> ManagedRef<U> {
350 unsafe {
351 let data = f(&*self.data);
352 ManagedRef {
353 lifetime: self.lifetime,
354 data: data as *const U,
355 }
356 }
357 }
358
359 pub unsafe fn try_map<U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<ManagedRef<U>> {
365 unsafe {
366 f(&*self.data).map(|data| ManagedRef {
367 lifetime: self.lifetime,
368 data: data as *const U,
369 })
370 }
371 }
372
373 pub unsafe fn as_ptr(&self) -> Option<*const T> {
379 if self.lifetime.exists() {
380 Some(self.data)
381 } else {
382 None
383 }
384 }
385}
386
387impl<T> TryFrom<ManagedValue<T>> for ManagedRef<T> {
388 type Error = ();
389
390 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
391 match value {
392 ManagedValue::Ref(value) => Ok(value),
393 _ => Err(()),
394 }
395 }
396}
397
398pub struct ManagedRefMut<T: ?Sized> {
402 lifetime: LifetimeRefMut,
403 data: *mut T,
404}
405
406unsafe impl<T: ?Sized> Send for ManagedRefMut<T> where T: Send {}
407unsafe impl<T: ?Sized> Sync for ManagedRefMut<T> where T: Sync {}
408
409impl<T: ?Sized> ManagedRefMut<T> {
410 pub fn new(data: &mut T, lifetime: LifetimeRefMut) -> Self {
412 Self {
413 lifetime,
414 data: data as *mut T,
415 }
416 }
417
418 pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeRefMut) -> Option<Self> {
426 if data.is_null() {
427 None
428 } else {
429 Some(Self { lifetime, data })
430 }
431 }
432
433 pub fn make(data: &mut T) -> (Self, Lifetime) {
439 let result = Lifetime::default();
440 (Self::new(data, result.borrow_mut().unwrap()), result)
441 }
442
443 pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
450 let result = Lifetime::default();
451 Some((
452 unsafe { Self::new_raw(data, result.borrow_mut().unwrap()) }?,
453 result,
454 ))
455 }
456
457 pub fn into_inner(self) -> (LifetimeRefMut, *mut T) {
459 (self.lifetime, self.data)
460 }
461
462 pub fn into_dynamic(self) -> DynamicManagedRefMut {
464 unsafe {
465 DynamicManagedRefMut::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
466 .unwrap()
467 }
468 }
469
470 pub fn lifetime(&self) -> &LifetimeRefMut {
472 &self.lifetime
473 }
474
475 pub fn borrow(&self) -> Option<ManagedRef<T>> {
477 Some(ManagedRef {
478 lifetime: self.lifetime.borrow()?,
479 data: self.data,
480 })
481 }
482
483 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
485 Some(ManagedRefMut {
486 lifetime: self.lifetime.borrow_mut()?,
487 data: self.data,
488 })
489 }
490
491 pub fn lazy(&self) -> ManagedLazy<T> {
493 ManagedLazy {
494 lifetime: self.lifetime.lazy(),
495 data: self.data,
496 }
497 }
498
499 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
502 unsafe { self.lifetime.read_ptr(self.data) }
503 }
504
505 pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
508 unsafe { self.lifetime.write_ptr(self.data) }
509 }
510
511 pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedRefMut<U> {
518 unsafe {
519 let data = f(&mut *self.data);
520 ManagedRefMut {
521 lifetime: self.lifetime,
522 data: data as *mut U,
523 }
524 }
525 }
526
527 pub unsafe fn try_map<U>(
533 self,
534 f: impl FnOnce(&mut T) -> Option<&mut U>,
535 ) -> Option<ManagedRefMut<U>> {
536 unsafe {
537 f(&mut *self.data).map(|data| ManagedRefMut {
538 lifetime: self.lifetime,
539 data: data as *mut U,
540 })
541 }
542 }
543
544 pub unsafe fn as_ptr(&self) -> Option<*const T> {
550 if self.lifetime.exists() {
551 Some(self.data)
552 } else {
553 None
554 }
555 }
556
557 pub unsafe fn as_mut_ptr(&mut self) -> Option<*mut T> {
564 if self.lifetime.exists() {
565 Some(self.data)
566 } else {
567 None
568 }
569 }
570}
571
572impl<T> TryFrom<ManagedValue<T>> for ManagedRefMut<T> {
573 type Error = ();
574
575 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
576 match value {
577 ManagedValue::RefMut(value) => Ok(value),
578 _ => Err(()),
579 }
580 }
581}
582
583pub struct ManagedLazy<T: ?Sized> {
590 lifetime: LifetimeLazy,
591 data: *mut T,
592}
593
594unsafe impl<T: ?Sized> Send for ManagedLazy<T> where T: Send {}
595unsafe impl<T: ?Sized> Sync for ManagedLazy<T> where T: Sync {}
596
597impl<T: ?Sized> Clone for ManagedLazy<T> {
598 fn clone(&self) -> Self {
599 Self {
600 lifetime: self.lifetime.clone(),
601 data: self.data,
602 }
603 }
604}
605
606impl<T: ?Sized> ManagedLazy<T> {
607 pub fn new(data: &mut T, lifetime: LifetimeLazy) -> Self {
609 Self {
610 lifetime,
611 data: data as *mut T,
612 }
613 }
614
615 pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeLazy) -> Option<Self> {
622 if data.is_null() {
623 None
624 } else {
625 Some(Self { lifetime, data })
626 }
627 }
628
629 pub fn make(data: &mut T) -> (Self, Lifetime) {
635 let result = Lifetime::default();
636 (Self::new(data, result.lazy()), result)
637 }
638
639 pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
645 let result = Lifetime::default();
646 Some((unsafe { Self::new_raw(data, result.lazy()) }?, result))
647 }
648
649 pub fn into_inner(self) -> (LifetimeLazy, *mut T) {
651 (self.lifetime, self.data)
652 }
653
654 pub fn into_dynamic(self) -> DynamicManagedLazy {
656 unsafe {
657 DynamicManagedLazy::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
658 .unwrap()
659 }
660 }
661
662 pub fn lifetime(&self) -> &LifetimeLazy {
664 &self.lifetime
665 }
666
667 pub fn borrow(&self) -> Option<ManagedRef<T>> {
669 Some(ManagedRef {
670 lifetime: self.lifetime.borrow()?,
671 data: self.data,
672 })
673 }
674
675 pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
677 Some(ManagedRefMut {
678 lifetime: self.lifetime.borrow_mut()?,
679 data: self.data,
680 })
681 }
682
683 pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
686 unsafe { self.lifetime.read_ptr(self.data) }
687 }
688
689 pub fn write(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
694 unsafe { self.lifetime.write_ptr(self.data) }
695 }
696
697 pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedLazy<U> {
704 unsafe {
705 let data = f(&mut *self.data);
706 ManagedLazy {
707 lifetime: self.lifetime,
708 data: data as *mut U,
709 }
710 }
711 }
712
713 pub unsafe fn try_map<U>(
719 self,
720 f: impl FnOnce(&mut T) -> Option<&mut U>,
721 ) -> Option<ManagedLazy<U>> {
722 unsafe {
723 f(&mut *self.data).map(|data| ManagedLazy {
724 lifetime: self.lifetime,
725 data: data as *mut U,
726 })
727 }
728 }
729
730 pub unsafe fn as_ptr(&self) -> Option<*const T> {
736 if self.lifetime.exists() {
737 Some(self.data)
738 } else {
739 None
740 }
741 }
742
743 pub unsafe fn as_mut_ptr(&self) -> Option<*mut T> {
750 if self.lifetime.exists() {
751 Some(self.data)
752 } else {
753 None
754 }
755 }
756}
757
758impl<T> TryFrom<ManagedValue<T>> for ManagedLazy<T> {
759 type Error = ();
760
761 fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
762 match value {
763 ManagedValue::Lazy(value) => Ok(value),
764 _ => Err(()),
765 }
766 }
767}
768
769pub struct DynamicManaged {
775 type_hash: TypeHash,
776 lifetime: Lifetime,
777 memory: *mut u8,
778 layout: Layout,
779 finalizer: Finalizer,
780 drop: bool,
781}
782
783unsafe impl Send for DynamicManaged {}
784unsafe impl Sync for DynamicManaged {}
785
786impl Drop for DynamicManaged {
787 fn drop(&mut self) {
788 if self.drop {
789 unsafe {
790 if self.memory.is_null() {
791 return;
792 }
793 let data_pointer = self.memory.cast::<()>();
794 self.finalizer.finalize(data_pointer);
795 non_zero_dealloc(self.memory, self.layout);
796 self.memory = std::ptr::null_mut();
797 }
798 }
799 }
800}
801
802impl DynamicManaged {
803 pub fn new<T: Finalize>(data: T) -> Result<Self, T> {
806 let layout = Layout::new::<T>().pad_to_align();
807 unsafe {
808 let memory = non_zero_alloc(layout);
809 if memory.is_null() {
810 Err(data)
811 } else {
812 memory.cast::<T>().write(data);
813 Ok(Self {
814 type_hash: TypeHash::of::<T>(),
815 lifetime: Default::default(),
816 memory,
817 layout,
818 finalizer: Finalizer::of::<T>(),
819 drop: true,
820 })
821 }
822 }
823 }
824
825 pub fn new_raw(
830 type_hash: TypeHash,
831 lifetime: Lifetime,
832 memory: *mut u8,
833 layout: Layout,
834 finalizer: impl Into<Finalizer>,
835 ) -> Option<Self> {
836 if memory.is_null() {
837 None
838 } else {
839 Some(Self {
840 type_hash,
841 lifetime,
842 memory,
843 layout,
844 finalizer: finalizer.into(),
845 drop: true,
846 })
847 }
848 }
849
850 pub fn new_uninitialized(
855 type_hash: TypeHash,
856 layout: Layout,
857 finalizer: impl Into<Finalizer>,
858 ) -> Self {
859 let layout = layout.pad_to_align();
860 let memory = unsafe { non_zero_alloc(layout) };
861 Self {
862 type_hash,
863 lifetime: Default::default(),
864 memory,
865 layout,
866 finalizer: finalizer.into(),
867 drop: true,
868 }
869 }
870
871 pub unsafe fn from_bytes(
879 type_hash: TypeHash,
880 lifetime: Lifetime,
881 bytes: Vec<u8>,
882 layout: Layout,
883 finalizer: impl Into<Finalizer>,
884 ) -> Self {
885 let layout = layout.pad_to_align();
886 let memory = unsafe { non_zero_alloc(layout) };
887 unsafe { memory.copy_from(bytes.as_ptr(), bytes.len()) };
888 Self {
889 type_hash,
890 lifetime,
891 memory,
892 layout,
893 finalizer: finalizer.into(),
894 drop: true,
895 }
896 }
897
898 #[allow(clippy::type_complexity)]
904 pub fn into_inner(mut self) -> (TypeHash, Lifetime, *mut u8, Layout, Finalizer) {
905 self.drop = false;
906 (
907 self.type_hash,
908 std::mem::take(&mut self.lifetime),
909 self.memory,
910 self.layout,
911 self.finalizer.clone(),
912 )
913 }
914
915 pub fn into_typed<T>(self) -> Result<Managed<T>, Self> {
918 Ok(Managed::new(self.consume()?))
919 }
920
921 pub fn renew(mut self) -> Self {
923 self.lifetime = Lifetime::default();
924 self
925 }
926
927 pub fn type_hash(&self) -> &TypeHash {
929 &self.type_hash
930 }
931
932 pub fn lifetime(&self) -> &Lifetime {
934 &self.lifetime
935 }
936
937 pub fn layout(&self) -> &Layout {
939 &self.layout
940 }
941
942 pub fn finalizer(&self) -> &Finalizer {
944 &self.finalizer
945 }
946
947 pub unsafe fn memory(&self) -> &[u8] {
954 unsafe { std::slice::from_raw_parts(self.memory, self.layout.size()) }
955 }
956
957 pub unsafe fn memory_mut(&mut self) -> &mut [u8] {
964 unsafe { std::slice::from_raw_parts_mut(self.memory, self.layout.size()) }
965 }
966
967 pub fn is<T>(&self) -> bool {
969 self.type_hash == TypeHash::of::<T>()
970 }
971
972 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
975 if self.type_hash == TypeHash::of::<T>() {
976 unsafe { self.lifetime.read_ptr(self.memory.cast::<T>()) }
977 } else {
978 None
979 }
980 }
981
982 pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
985 if self.type_hash == TypeHash::of::<T>() {
986 unsafe { self.lifetime.write_ptr(self.memory.cast::<T>()) }
987 } else {
988 None
989 }
990 }
991
992 pub fn consume<T>(mut self) -> Result<T, Self> {
996 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
997 if self.memory.is_null() {
998 return Err(self);
999 }
1000 self.drop = false;
1001 let mut result = MaybeUninit::<T>::uninit();
1002 unsafe {
1003 result.as_mut_ptr().copy_from(self.memory.cast::<T>(), 1);
1004 non_zero_dealloc(self.memory, self.layout);
1005 self.memory = std::ptr::null_mut();
1006 Ok(result.assume_init())
1007 }
1008 } else {
1009 Err(self)
1010 }
1011 }
1012
1013 pub fn move_into_ref(self, target: DynamicManagedRefMut) -> Result<(), Self> {
1019 if self.type_hash == target.type_hash && self.memory != target.data {
1020 if self.memory.is_null() {
1021 return Err(self);
1022 }
1023 let (_, _, memory, layout, _) = self.into_inner();
1024 unsafe {
1025 target.data.copy_from(memory, layout.size());
1026 non_zero_dealloc(memory, layout);
1027 }
1028 Ok(())
1029 } else {
1030 Err(self)
1031 }
1032 }
1033
1034 pub fn move_into_lazy(self, target: DynamicManagedLazy) -> Result<(), Self> {
1040 if self.type_hash == target.type_hash && self.memory != target.data {
1041 if self.memory.is_null() {
1042 return Err(self);
1043 }
1044 let (_, _, memory, layout, _) = self.into_inner();
1045 unsafe {
1046 target.data.copy_from(memory, layout.size());
1047 non_zero_dealloc(memory, layout);
1048 }
1049 Ok(())
1050 } else {
1051 Err(self)
1052 }
1053 }
1054
1055 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1057 unsafe { DynamicManagedRef::new_raw(self.type_hash, self.lifetime.borrow()?, self.memory) }
1058 }
1059
1060 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1062 unsafe {
1063 DynamicManagedRefMut::new_raw(self.type_hash, self.lifetime.borrow_mut()?, self.memory)
1064 }
1065 }
1066
1067 pub fn lazy(&self) -> DynamicManagedLazy {
1069 unsafe {
1070 DynamicManagedLazy::new_raw(self.type_hash, self.lifetime.lazy(), self.memory).unwrap()
1071 }
1072 }
1073
1074 pub unsafe fn map<T, U: Finalize>(self, f: impl FnOnce(T) -> U) -> Option<Self> {
1081 let data = self.consume::<T>().ok()?;
1082 let data = f(data);
1083 Self::new(data).ok()
1084 }
1085
1086 pub unsafe fn try_map<T, U: Finalize>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Self> {
1093 let data = self.consume::<T>().ok()?;
1094 let data = f(data)?;
1095 Self::new(data).ok()
1096 }
1097
1098 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1104 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
1105 Some(self.memory.cast::<T>())
1106 } else {
1107 None
1108 }
1109 }
1110
1111 pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1117 if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
1118 Some(self.memory.cast::<T>())
1119 } else {
1120 None
1121 }
1122 }
1123
1124 pub unsafe fn as_ptr_raw(&self) -> *const u8 {
1130 self.memory
1131 }
1132
1133 pub unsafe fn as_mut_ptr_raw(&mut self) -> *mut u8 {
1139 self.memory
1140 }
1141}
1142
1143impl TryFrom<DynamicManagedValue> for DynamicManaged {
1144 type Error = ();
1145
1146 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1147 match value {
1148 DynamicManagedValue::Owned(value) => Ok(value),
1149 _ => Err(()),
1150 }
1151 }
1152}
1153
1154pub struct DynamicManagedRef {
1158 type_hash: TypeHash,
1159 lifetime: LifetimeRef,
1160 data: *const u8,
1161}
1162
1163unsafe impl Send for DynamicManagedRef {}
1164unsafe impl Sync for DynamicManagedRef {}
1165
1166impl DynamicManagedRef {
1167 pub fn new<T: ?Sized>(data: &T, lifetime: LifetimeRef) -> Self {
1169 Self {
1170 type_hash: TypeHash::of::<T>(),
1171 lifetime,
1172 data: data as *const T as *const u8,
1173 }
1174 }
1175
1176 pub unsafe fn new_raw(
1184 type_hash: TypeHash,
1185 lifetime: LifetimeRef,
1186 data: *const u8,
1187 ) -> Option<Self> {
1188 if data.is_null() {
1189 None
1190 } else {
1191 Some(Self {
1192 type_hash,
1193 lifetime,
1194 data,
1195 })
1196 }
1197 }
1198
1199 pub fn make<T: ?Sized>(data: &T) -> (Self, Lifetime) {
1202 let result = Lifetime::default();
1203 (Self::new(data, result.borrow().unwrap()), result)
1204 }
1205
1206 pub fn into_inner(self) -> (TypeHash, LifetimeRef, *const u8) {
1208 (self.type_hash, self.lifetime, self.data)
1209 }
1210
1211 pub fn into_typed<T>(self) -> Result<ManagedRef<T>, Self> {
1213 if self.type_hash == TypeHash::of::<T>() {
1214 unsafe { Ok(ManagedRef::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1215 } else {
1216 Err(self)
1217 }
1218 }
1219
1220 pub fn type_hash(&self) -> &TypeHash {
1222 &self.type_hash
1223 }
1224
1225 pub fn lifetime(&self) -> &LifetimeRef {
1227 &self.lifetime
1228 }
1229
1230 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1232 Some(DynamicManagedRef {
1233 type_hash: self.type_hash,
1234 lifetime: self.lifetime.borrow()?,
1235 data: self.data,
1236 })
1237 }
1238
1239 pub unsafe fn lazy_immutable(&self) -> DynamicManagedLazy {
1246 DynamicManagedLazy {
1247 type_hash: self.type_hash,
1248 lifetime: self.lifetime.lazy(),
1249 data: self.data as *mut u8,
1250 }
1251 }
1252
1253 pub fn is<T>(&self) -> bool {
1255 self.type_hash == TypeHash::of::<T>()
1256 }
1257
1258 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1261 if self.type_hash == TypeHash::of::<T>() {
1262 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1263 } else {
1264 None
1265 }
1266 }
1267
1268 pub unsafe fn map<T, U>(self, f: impl FnOnce(&T) -> &U) -> Option<Self> {
1275 if self.type_hash == TypeHash::of::<T>() {
1276 unsafe {
1277 let data = f(&*self.data.cast::<T>());
1278 Some(Self {
1279 type_hash: TypeHash::of::<U>(),
1280 lifetime: self.lifetime,
1281 data: data as *const U as *const u8,
1282 })
1283 }
1284 } else {
1285 None
1286 }
1287 }
1288
1289 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<Self> {
1295 if self.type_hash == TypeHash::of::<T>() {
1296 unsafe {
1297 let data = f(&*self.data.cast::<T>())?;
1298 Some(Self {
1299 type_hash: TypeHash::of::<U>(),
1300 lifetime: self.lifetime,
1301 data: data as *const U as *const u8,
1302 })
1303 }
1304 } else {
1305 None
1306 }
1307 }
1308
1309 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1315 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1316 Some(self.data.cast::<T>())
1317 } else {
1318 None
1319 }
1320 }
1321
1322 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1328 if self.lifetime.exists() {
1329 Some(self.data)
1330 } else {
1331 None
1332 }
1333 }
1334}
1335
1336impl TryFrom<DynamicManagedValue> for DynamicManagedRef {
1337 type Error = ();
1338
1339 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1340 match value {
1341 DynamicManagedValue::Ref(value) => Ok(value),
1342 _ => Err(()),
1343 }
1344 }
1345}
1346
1347pub struct DynamicManagedRefMut {
1351 type_hash: TypeHash,
1352 lifetime: LifetimeRefMut,
1353 data: *mut u8,
1354}
1355
1356unsafe impl Send for DynamicManagedRefMut {}
1357unsafe impl Sync for DynamicManagedRefMut {}
1358
1359impl DynamicManagedRefMut {
1360 pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeRefMut) -> Self {
1362 Self {
1363 type_hash: TypeHash::of::<T>(),
1364 lifetime,
1365 data: data as *mut T as *mut u8,
1366 }
1367 }
1368
1369 pub unsafe fn new_raw(
1377 type_hash: TypeHash,
1378 lifetime: LifetimeRefMut,
1379 data: *mut u8,
1380 ) -> Option<Self> {
1381 if data.is_null() {
1382 None
1383 } else {
1384 Some(Self {
1385 type_hash,
1386 lifetime,
1387 data,
1388 })
1389 }
1390 }
1391
1392 pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1395 let result = Lifetime::default();
1396 (Self::new(data, result.borrow_mut().unwrap()), result)
1397 }
1398
1399 pub fn into_inner(self) -> (TypeHash, LifetimeRefMut, *mut u8) {
1401 (self.type_hash, self.lifetime, self.data)
1402 }
1403
1404 pub fn into_typed<T>(self) -> Result<ManagedRefMut<T>, Self> {
1406 if self.type_hash == TypeHash::of::<T>() {
1407 unsafe { Ok(ManagedRefMut::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1408 } else {
1409 Err(self)
1410 }
1411 }
1412
1413 pub fn type_hash(&self) -> &TypeHash {
1415 &self.type_hash
1416 }
1417
1418 pub fn lifetime(&self) -> &LifetimeRefMut {
1420 &self.lifetime
1421 }
1422
1423 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1425 Some(DynamicManagedRef {
1426 type_hash: self.type_hash,
1427 lifetime: self.lifetime.borrow()?,
1428 data: self.data,
1429 })
1430 }
1431
1432 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1434 Some(DynamicManagedRefMut {
1435 type_hash: self.type_hash,
1436 lifetime: self.lifetime.borrow_mut()?,
1437 data: self.data,
1438 })
1439 }
1440
1441 pub fn lazy(&self) -> DynamicManagedLazy {
1443 DynamicManagedLazy {
1444 type_hash: self.type_hash,
1445 lifetime: self.lifetime.lazy(),
1446 data: self.data,
1447 }
1448 }
1449
1450 pub fn is<T>(&self) -> bool {
1452 self.type_hash == TypeHash::of::<T>()
1453 }
1454
1455 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1458 if self.type_hash == TypeHash::of::<T>() {
1459 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1460 } else {
1461 None
1462 }
1463 }
1464
1465 pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
1468 if self.type_hash == TypeHash::of::<T>() {
1469 unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1470 } else {
1471 None
1472 }
1473 }
1474
1475 pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1482 if self.type_hash == TypeHash::of::<T>() {
1483 unsafe {
1484 let data = f(&mut *self.data.cast::<T>());
1485 Some(Self {
1486 type_hash: TypeHash::of::<U>(),
1487 lifetime: self.lifetime,
1488 data: data as *mut U as *mut u8,
1489 })
1490 }
1491 } else {
1492 None
1493 }
1494 }
1495
1496 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1502 if self.type_hash == TypeHash::of::<T>() {
1503 unsafe {
1504 let data = f(&mut *self.data.cast::<T>())?;
1505 Some(Self {
1506 type_hash: TypeHash::of::<U>(),
1507 lifetime: self.lifetime,
1508 data: data as *mut U as *mut u8,
1509 })
1510 }
1511 } else {
1512 None
1513 }
1514 }
1515
1516 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1522 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1523 Some(self.data.cast::<T>())
1524 } else {
1525 None
1526 }
1527 }
1528
1529 pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1535 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1536 Some(self.data.cast::<T>())
1537 } else {
1538 None
1539 }
1540 }
1541
1542 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1548 if self.lifetime.exists() {
1549 Some(self.data)
1550 } else {
1551 None
1552 }
1553 }
1554
1555 pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1561 if self.lifetime.exists() {
1562 Some(self.data)
1563 } else {
1564 None
1565 }
1566 }
1567}
1568
1569impl TryFrom<DynamicManagedValue> for DynamicManagedRefMut {
1570 type Error = ();
1571
1572 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1573 match value {
1574 DynamicManagedValue::RefMut(value) => Ok(value),
1575 _ => Err(()),
1576 }
1577 }
1578}
1579
1580pub struct DynamicManagedLazy {
1585 type_hash: TypeHash,
1586 lifetime: LifetimeLazy,
1587 data: *mut u8,
1588}
1589
1590unsafe impl Send for DynamicManagedLazy {}
1591unsafe impl Sync for DynamicManagedLazy {}
1592
1593impl Clone for DynamicManagedLazy {
1594 fn clone(&self) -> Self {
1595 Self {
1596 type_hash: self.type_hash,
1597 lifetime: self.lifetime.clone(),
1598 data: self.data,
1599 }
1600 }
1601}
1602
1603impl DynamicManagedLazy {
1604 pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeLazy) -> Self {
1606 Self {
1607 type_hash: TypeHash::of::<T>(),
1608 lifetime,
1609 data: data as *mut T as *mut u8,
1610 }
1611 }
1612
1613 pub unsafe fn new_raw(
1621 type_hash: TypeHash,
1622 lifetime: LifetimeLazy,
1623 data: *mut u8,
1624 ) -> Option<Self> {
1625 if data.is_null() {
1626 None
1627 } else {
1628 Some(Self {
1629 type_hash,
1630 lifetime,
1631 data,
1632 })
1633 }
1634 }
1635
1636 pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1639 let result = Lifetime::default();
1640 (Self::new(data, result.lazy()), result)
1641 }
1642
1643 pub fn into_inner(self) -> (TypeHash, LifetimeLazy, *mut u8) {
1645 (self.type_hash, self.lifetime, self.data)
1646 }
1647
1648 pub fn into_typed<T>(self) -> Result<ManagedLazy<T>, Self> {
1650 if self.type_hash == TypeHash::of::<T>() {
1651 unsafe { Ok(ManagedLazy::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1652 } else {
1653 Err(self)
1654 }
1655 }
1656
1657 pub fn type_hash(&self) -> &TypeHash {
1659 &self.type_hash
1660 }
1661
1662 pub fn lifetime(&self) -> &LifetimeLazy {
1664 &self.lifetime
1665 }
1666
1667 pub fn is<T>(&self) -> bool {
1669 self.type_hash == TypeHash::of::<T>()
1670 }
1671
1672 pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1675 if self.type_hash == TypeHash::of::<T>() {
1676 unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1677 } else {
1678 None
1679 }
1680 }
1681
1682 pub fn write<T>(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
1687 if self.type_hash == TypeHash::of::<T>() {
1688 unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1689 } else {
1690 None
1691 }
1692 }
1693
1694 pub fn borrow(&self) -> Option<DynamicManagedRef> {
1696 Some(DynamicManagedRef {
1697 type_hash: self.type_hash,
1698 lifetime: self.lifetime.borrow()?,
1699 data: self.data,
1700 })
1701 }
1702
1703 pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1705 Some(DynamicManagedRefMut {
1706 type_hash: self.type_hash,
1707 lifetime: self.lifetime.borrow_mut()?,
1708 data: self.data,
1709 })
1710 }
1711
1712 pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1719 if self.type_hash == TypeHash::of::<T>() {
1720 unsafe {
1721 let data = f(&mut *self.data.cast::<T>());
1722 Some(Self {
1723 type_hash: TypeHash::of::<U>(),
1724 lifetime: self.lifetime,
1725 data: data as *mut U as *mut u8,
1726 })
1727 }
1728 } else {
1729 None
1730 }
1731 }
1732
1733 pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1739 if self.type_hash == TypeHash::of::<T>() {
1740 unsafe {
1741 let data = f(&mut *self.data.cast::<T>())?;
1742 Some(Self {
1743 type_hash: TypeHash::of::<U>(),
1744 lifetime: self.lifetime,
1745 data: data as *mut U as *mut u8,
1746 })
1747 }
1748 } else {
1749 None
1750 }
1751 }
1752
1753 pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1759 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1760 Some(self.data.cast::<T>())
1761 } else {
1762 None
1763 }
1764 }
1765
1766 pub unsafe fn as_mut_ptr<T>(&self) -> Option<*mut T> {
1772 if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1773 Some(self.data.cast::<T>())
1774 } else {
1775 None
1776 }
1777 }
1778
1779 pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1785 if self.lifetime.exists() {
1786 Some(self.data)
1787 } else {
1788 None
1789 }
1790 }
1791
1792 pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1798 if self.lifetime.exists() {
1799 Some(self.data)
1800 } else {
1801 None
1802 }
1803 }
1804}
1805
1806impl TryFrom<DynamicManagedValue> for DynamicManagedLazy {
1807 type Error = ();
1808
1809 fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1810 match value {
1811 DynamicManagedValue::Lazy(value) => Ok(value),
1812 _ => Err(()),
1813 }
1814 }
1815}
1816
1817#[cfg(test)]
1818mod tests {
1819 use super::*;
1820 use std::any::Any;
1821
1822 fn is_async<T: Send + Sync + ?Sized>() {}
1823
1824 #[test]
1825 fn test_managed() {
1826 is_async::<Managed<()>>();
1827 is_async::<ManagedRef<()>>();
1828 is_async::<ManagedRefMut<()>>();
1829 is_async::<ManagedLazy<()>>();
1830 is_async::<ManagedValue<()>>();
1831
1832 let mut value = Managed::new(42);
1833 let mut value_ref = value.borrow_mut().unwrap();
1834 assert!(value_ref.write().is_some());
1835 let mut value_ref2 = value_ref.borrow_mut().unwrap();
1836 assert!(value_ref.write().is_some());
1837 assert!(value_ref2.write().is_some());
1838 drop(value_ref);
1839 let value_ref = value.borrow().unwrap();
1840 assert!(value.borrow().is_some());
1841 assert!(value.borrow_mut().is_none());
1842 drop(value_ref);
1843 assert!(value.borrow().is_some());
1844 assert!(value.borrow_mut().is_some());
1845 *value.write().unwrap() = 40;
1846 assert_eq!(*value.read().unwrap(), 40);
1847 *value.borrow_mut().unwrap().write().unwrap() = 2;
1848 assert_eq!(*value.read().unwrap(), 2);
1849 let value_ref = value.borrow().unwrap();
1850 let value_ref2 = value_ref.borrow().unwrap();
1851 drop(value_ref);
1852 assert!(value_ref2.read().is_some());
1853 let value_ref = value.borrow().unwrap();
1854 let value_lazy = value.lazy();
1855 assert_eq!(*value_lazy.read().unwrap(), 2);
1856 *value_lazy.write().unwrap() = 42;
1857 assert_eq!(*value_lazy.read().unwrap(), 42);
1858 drop(value);
1859 assert!(value_ref.read().is_none());
1860 assert!(value_ref2.read().is_none());
1861 assert!(value_lazy.read().is_none());
1862 }
1863
1864 #[test]
1865 fn test_dynamic_managed() {
1866 is_async::<DynamicManaged>();
1867 is_async::<DynamicManagedRef>();
1868 is_async::<DynamicManagedRefMut>();
1869 is_async::<DynamicManagedLazy>();
1870 is_async::<DynamicManagedValue>();
1871
1872 let mut value = DynamicManaged::new(42).unwrap();
1873 let mut value_ref = value.borrow_mut().unwrap();
1874 assert!(value_ref.write::<i32>().is_some());
1875 let mut value_ref2 = value_ref.borrow_mut().unwrap();
1876 assert!(value_ref.write::<i32>().is_some());
1877 assert!(value_ref2.write::<i32>().is_some());
1878 drop(value_ref);
1879 let value_ref = value.borrow().unwrap();
1880 assert!(value.borrow().is_some());
1881 assert!(value.borrow_mut().is_none());
1882 drop(value_ref);
1883 assert!(value.borrow().is_some());
1884 assert!(value.borrow_mut().is_some());
1885 *value.write::<i32>().unwrap() = 40;
1886 assert_eq!(*value.read::<i32>().unwrap(), 40);
1887 *value.borrow_mut().unwrap().write::<i32>().unwrap() = 2;
1888 assert_eq!(*value.read::<i32>().unwrap(), 2);
1889 let value_ref = value.borrow().unwrap();
1890 let value_ref2 = value_ref.borrow().unwrap();
1891 drop(value_ref);
1892 assert!(value_ref2.read::<i32>().is_some());
1893 let value_ref = value.borrow().unwrap();
1894 let value_lazy = value.lazy();
1895 assert_eq!(*value_lazy.read::<i32>().unwrap(), 2);
1896 *value_lazy.write::<i32>().unwrap() = 42;
1897 assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1898 drop(value);
1899 assert!(value_ref.read::<i32>().is_none());
1900 assert!(value_ref2.read::<i32>().is_none());
1901 assert!(value_lazy.read::<i32>().is_none());
1902 let value = DynamicManaged::new("hello".to_owned()).unwrap();
1903 let value = value.consume::<String>().ok().unwrap();
1904 assert_eq!(value.as_str(), "hello");
1905 }
1906
1907 #[test]
1908 fn test_conversion() {
1909 let value = Managed::new(42);
1910 assert_eq!(*value.read().unwrap(), 42);
1911 let value = value.into_dynamic().ok().unwrap();
1912 assert_eq!(*value.read::<i32>().unwrap(), 42);
1913 let mut value = value.into_typed::<i32>().ok().unwrap();
1914 assert_eq!(*value.read().unwrap(), 42);
1915
1916 let value_ref = value.borrow().unwrap();
1917 assert_eq!(*value.read().unwrap(), 42);
1918 let value_ref = value_ref.into_dynamic();
1919 assert_eq!(*value_ref.read::<i32>().unwrap(), 42);
1920 let value_ref = value_ref.into_typed::<i32>().ok().unwrap();
1921 assert_eq!(*value_ref.read().unwrap(), 42);
1922 drop(value_ref);
1923
1924 let value_ref_mut = value.borrow_mut().unwrap();
1925 assert_eq!(*value.read().unwrap(), 42);
1926 let value_ref_mut = value_ref_mut.into_dynamic();
1927 assert_eq!(*value_ref_mut.read::<i32>().unwrap(), 42);
1928 let value_ref_mut = value_ref_mut.into_typed::<i32>().ok().unwrap();
1929 assert_eq!(*value_ref_mut.read().unwrap(), 42);
1930
1931 let value_lazy = value.lazy();
1932 assert_eq!(*value.read().unwrap(), 42);
1933 let value_lazy = value_lazy.into_dynamic();
1934 assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1935 let value_lazy = value_lazy.into_typed::<i32>().ok().unwrap();
1936 assert_eq!(*value_lazy.read().unwrap(), 42);
1937 }
1938
1939 #[test]
1940 fn test_unsized() {
1941 let lifetime = Lifetime::default();
1942 let mut data = 42usize;
1943 {
1944 let foo = ManagedRef::<dyn Any>::new(&data, lifetime.borrow().unwrap());
1945 assert_eq!(
1946 *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1947 42usize
1948 );
1949 }
1950 {
1951 let mut foo = ManagedRefMut::<dyn Any>::new(&mut data, lifetime.borrow_mut().unwrap());
1952 *foo.write().unwrap().downcast_mut::<usize>().unwrap() = 100;
1953 }
1954 {
1955 let foo = ManagedLazy::<dyn Any>::new(&mut data, lifetime.lazy());
1956 assert_eq!(
1957 *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1958 100usize
1959 );
1960 }
1961
1962 let lifetime = Lifetime::default();
1963 let mut data = [0, 1, 2, 3];
1964 {
1965 let foo = ManagedRef::<[i32]>::new(&data, lifetime.borrow().unwrap());
1966 assert_eq!(*foo.read().unwrap(), [0, 1, 2, 3]);
1967 }
1968 {
1969 let mut foo = ManagedRefMut::<[i32]>::new(&mut data, lifetime.borrow_mut().unwrap());
1970 foo.write().unwrap().sort_by(|a, b| a.cmp(b).reverse());
1971 }
1972 {
1973 let foo = ManagedLazy::<[i32]>::new(&mut data, lifetime.lazy());
1974 assert_eq!(*foo.read().unwrap(), [3, 2, 1, 0]);
1975 }
1976 }
1977
1978 #[test]
1979 fn test_moves() {
1980 let mut value = Managed::new(42);
1981 assert_eq!(*value.read().unwrap(), 42);
1982 {
1983 let value_ref = value.borrow_mut().unwrap();
1984 Managed::new(1).move_into_ref(value_ref).ok().unwrap();
1985 assert_eq!(*value.read().unwrap(), 1);
1986 }
1987 {
1988 let value_lazy = value.lazy();
1989 Managed::new(2).move_into_lazy(value_lazy).ok().unwrap();
1990 assert_eq!(*value.read().unwrap(), 2);
1991 }
1992
1993 let mut value = DynamicManaged::new(42).unwrap();
1994 assert_eq!(*value.read::<i32>().unwrap(), 42);
1995 {
1996 let value_ref = value.borrow_mut().unwrap();
1997 DynamicManaged::new(1)
1998 .unwrap()
1999 .move_into_ref(value_ref)
2000 .ok()
2001 .unwrap();
2002 assert_eq!(*value.read::<i32>().unwrap(), 1);
2003 }
2004 {
2005 let value_lazy = value.lazy();
2006 DynamicManaged::new(2)
2007 .unwrap()
2008 .move_into_lazy(value_lazy)
2009 .ok()
2010 .unwrap();
2011 assert_eq!(*value.read::<i32>().unwrap(), 2);
2012 }
2013 }
2014
2015 #[test]
2016 fn test_move_invalidation() {
2017 let value = Managed::new(42);
2018 let value_ref = value.borrow().unwrap();
2019 assert_eq!(value.lifetime().tag(), value_ref.lifetime().tag());
2020 assert!(value_ref.lifetime().exists());
2021 let value = Box::new(value);
2022 assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
2023 assert!(!value_ref.lifetime().exists());
2024 let value = *value;
2025 assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
2026 assert!(!value_ref.lifetime().exists());
2027 }
2028}