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