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