1use crate::registry::Registry;
35use intuicio_data::{
36 lifetime::*,
37 managed::{gc::*, *},
38 shared::*,
39};
40use std::{
41 cell::{Ref, RefMut},
42 marker::PhantomData,
43};
44
45pub trait ValueTransformer {
50 type Type;
52 type Borrow<'r>
54 where
55 Self::Type: 'r;
56 type BorrowMut<'r>
58 where
59 Self::Type: 'r;
60 type Dependency;
63 type Owned;
65 type Ref;
67 type RefMut;
69
70 fn from_owned(registry: &Registry, value: Self::Type) -> Self::Owned;
72 fn from_ref(
74 registry: &Registry,
75 value: &Self::Type,
76 dependency: Option<Self::Dependency>,
77 ) -> Self::Ref;
78 fn from_ref_mut(
80 registry: &Registry,
81 value: &mut Self::Type,
82 dependency: Option<Self::Dependency>,
83 ) -> Self::RefMut;
84 fn into_owned(value: Self::Owned) -> Self::Type;
86 fn into_ref(value: &Self::Ref) -> Self::Borrow<'_>;
88 fn into_ref_mut(value: &mut Self::RefMut) -> Self::BorrowMut<'_>;
90}
91
92pub trait ValueDependency<T> {
97 fn as_ref(value: &T) -> Self;
99 fn as_ref_mut(value: &mut T) -> Self;
105}
106
107pub struct SharedValueTransformer<T: Default + Clone + 'static>(PhantomData<fn() -> T>);
112
113impl<T: Default + Clone + 'static> ValueTransformer for SharedValueTransformer<T> {
114 type Type = T;
115 type Borrow<'r> = Ref<'r, T>;
116 type BorrowMut<'r> = RefMut<'r, T>;
117 type Dependency = ();
118 type Owned = Shared<T>;
119 type Ref = Shared<T>;
120 type RefMut = Shared<T>;
121
122 fn from_owned(_: &Registry, value: Self::Type) -> Self::Owned {
123 Shared::new(value)
124 }
125
126 fn from_ref(_: &Registry, value: &Self::Type, _: Option<Self::Dependency>) -> Self::Ref {
127 Shared::new(value.clone())
128 }
129
130 fn from_ref_mut(
131 _: &Registry,
132 value: &mut Self::Type,
133 _: Option<Self::Dependency>,
134 ) -> Self::RefMut {
135 Shared::new(value.clone())
136 }
137
138 fn into_owned(value: Self::Owned) -> Self::Type {
139 value.read().unwrap().clone()
140 }
141
142 fn into_ref(value: &Self::Ref) -> Self::Borrow<'_> {
143 value.read().unwrap()
144 }
145
146 fn into_ref_mut(value: &mut Self::RefMut) -> Self::BorrowMut<'_> {
147 value.write().unwrap()
148 }
149}
150
151pub struct ManagedValueTransformer<T>(PhantomData<fn() -> T>);
155
156impl<T> ValueTransformer for ManagedValueTransformer<T> {
157 type Type = T;
158 type Borrow<'r>
159 = ValueReadAccess<'r, T>
160 where
161 Self::Type: 'r;
162 type BorrowMut<'r>
163 = ValueWriteAccess<'r, T>
164 where
165 Self::Type: 'r;
166 type Dependency = ManagedValueDependency;
167 type Owned = Managed<T>;
168 type Ref = ManagedRef<T>;
169 type RefMut = ManagedRefMut<T>;
170
171 fn from_owned(_: &Registry, value: Self::Type) -> Self::Owned {
172 Managed::new(value)
173 }
174
175 fn from_ref(
176 _: &Registry,
177 value: &Self::Type,
178 dependency: Option<Self::Dependency>,
179 ) -> Self::Ref {
180 if let ManagedValueDependency::Ref(lifetime) =
181 dependency.expect("`ManagedRef` require dependency for lifetime bound!")
182 {
183 ManagedRef::new(value, lifetime)
184 } else {
185 panic!("Could not borrow lifetime to create `ManagedRef`!")
186 }
187 }
188
189 fn from_ref_mut(
190 _: &Registry,
191 value: &mut Self::Type,
192 dependency: Option<Self::Dependency>,
193 ) -> Self::RefMut {
194 if let ManagedValueDependency::RefMut(lifetime) =
195 dependency.expect("`ManagedRefMut` require dependency for lifetime bound!")
196 {
197 ManagedRefMut::new(value, lifetime)
198 } else {
199 panic!("Could not borrow lifetime mutably to create `ManagedRefMut`!")
200 }
201 }
202
203 fn into_owned(value: Self::Owned) -> Self::Type {
204 value.consume().ok().unwrap()
205 }
206
207 fn into_ref(value: &Self::Ref) -> Self::Borrow<'_> {
208 value.read().unwrap()
209 }
210
211 fn into_ref_mut(value: &mut Self::RefMut) -> Self::BorrowMut<'_> {
212 value.write().unwrap()
213 }
214}
215
216pub struct ManagedGcValueTransformer<T>(PhantomData<fn() -> T>);
219
220impl<T> ValueTransformer for ManagedGcValueTransformer<T> {
221 type Type = T;
222 type Borrow<'r>
223 = ValueReadAccess<'r, T>
224 where
225 Self::Type: 'r;
226 type BorrowMut<'r>
227 = ValueWriteAccess<'r, T>
228 where
229 Self::Type: 'r;
230 type Dependency = ManagedValueDependency;
231 type Owned = ManagedGc<T>;
232 type Ref = ManagedRef<T>;
233 type RefMut = ManagedRefMut<T>;
234
235 fn from_owned(_: &Registry, value: Self::Type) -> Self::Owned {
236 ManagedGc::new(value)
237 }
238
239 fn from_ref(
240 _: &Registry,
241 value: &Self::Type,
242 dependency: Option<Self::Dependency>,
243 ) -> Self::Ref {
244 if let ManagedValueDependency::Ref(lifetime) =
245 dependency.expect("`ManagedRef` require dependency for lifetime bound!")
246 {
247 ManagedRef::new(value, lifetime)
248 } else {
249 panic!("Could not borrow lifetime to create `ManagedRef`!")
250 }
251 }
252
253 fn from_ref_mut(
254 _: &Registry,
255 value: &mut Self::Type,
256 dependency: Option<Self::Dependency>,
257 ) -> Self::RefMut {
258 if let ManagedValueDependency::RefMut(lifetime) =
259 dependency.expect("`ManagedRefMut` require dependency for lifetime bound!")
260 {
261 ManagedRefMut::new(value, lifetime)
262 } else {
263 panic!("Could not borrow lifetime mutably to create `ManagedRefMut`!")
264 }
265 }
266
267 fn into_owned(value: Self::Owned) -> Self::Type {
268 value.consume().ok().unwrap()
269 }
270
271 fn into_ref(value: &Self::Ref) -> Self::Borrow<'_> {
272 value.read().unwrap()
273 }
274
275 fn into_ref_mut(value: &mut Self::RefMut) -> Self::BorrowMut<'_> {
276 value.write().unwrap()
277 }
278}
279
280pub struct DynamicManagedValueTransformer<T: 'static>(PhantomData<fn() -> T>);
284
285impl<T: 'static> ValueTransformer for DynamicManagedValueTransformer<T> {
286 type Type = T;
287 type Borrow<'r>
288 = ValueReadAccess<'r, T>
289 where
290 Self::Type: 'r;
291 type BorrowMut<'r>
292 = ValueWriteAccess<'r, T>
293 where
294 Self::Type: 'r;
295 type Dependency = ManagedValueDependency;
296 type Owned = DynamicManaged;
297 type Ref = DynamicManagedRef;
298 type RefMut = DynamicManagedRefMut;
299
300 fn from_owned(_: &Registry, value: Self::Type) -> Self::Owned {
301 DynamicManaged::new(value).ok().unwrap()
302 }
303
304 fn from_ref(
305 _: &Registry,
306 value: &Self::Type,
307 dependency: Option<Self::Dependency>,
308 ) -> Self::Ref {
309 if let ManagedValueDependency::Ref(lifetime) =
310 dependency.expect("`DynamicManagedRef` require dependency for lifetime bound!")
311 {
312 DynamicManagedRef::new(value, lifetime)
313 } else {
314 panic!("Could not borrow lifetime to create `DynamicManagedRef`!")
315 }
316 }
317
318 fn from_ref_mut(
319 _: &Registry,
320 value: &mut Self::Type,
321 dependency: Option<Self::Dependency>,
322 ) -> Self::RefMut {
323 if let ManagedValueDependency::RefMut(lifetime) =
324 dependency.expect("`DynamicManagedRefMut` require dependency for lifetime bound!")
325 {
326 DynamicManagedRefMut::new(value, lifetime)
327 } else {
328 panic!("Could not borrow lifetime mutably to create `DynamicManagedRefMut`!")
329 }
330 }
331
332 fn into_owned(value: Self::Owned) -> Self::Type {
333 value.consume().ok().unwrap()
334 }
335
336 fn into_ref(value: &Self::Ref) -> Self::Borrow<'_> {
337 value.read().unwrap()
338 }
339
340 fn into_ref_mut(value: &mut Self::RefMut) -> Self::BorrowMut<'_> {
341 value.write().unwrap()
342 }
343}
344
345pub struct DynamicManagedGcValueTransformer<T: 'static>(PhantomData<fn() -> T>);
348
349impl<T: 'static> ValueTransformer for DynamicManagedGcValueTransformer<T> {
350 type Type = T;
351 type Borrow<'r>
352 = ValueReadAccess<'r, T>
353 where
354 Self::Type: 'r;
355 type BorrowMut<'r>
356 = ValueWriteAccess<'r, T>
357 where
358 Self::Type: 'r;
359 type Dependency = ManagedValueDependency;
360 type Owned = DynamicManagedGc;
361 type Ref = DynamicManagedRef;
362 type RefMut = DynamicManagedRefMut;
363
364 fn from_owned(_: &Registry, value: Self::Type) -> Self::Owned {
365 DynamicManagedGc::new(value)
366 }
367
368 fn from_ref(
369 _: &Registry,
370 value: &Self::Type,
371 dependency: Option<Self::Dependency>,
372 ) -> Self::Ref {
373 if let ManagedValueDependency::Ref(lifetime) =
374 dependency.expect("`DynamicManagedRef` require dependency for lifetime bound!")
375 {
376 DynamicManagedRef::new(value, lifetime)
377 } else {
378 panic!("Could not borrow lifetime to create `DynamicManagedRef`!")
379 }
380 }
381
382 fn from_ref_mut(
383 _: &Registry,
384 value: &mut Self::Type,
385 dependency: Option<Self::Dependency>,
386 ) -> Self::RefMut {
387 if let ManagedValueDependency::RefMut(lifetime) =
388 dependency.expect("`DynamicManagedRefMut` require dependency for lifetime bound!")
389 {
390 DynamicManagedRefMut::new(value, lifetime)
391 } else {
392 panic!("Could not borrow lifetime mutably to create `DynamicManagedRefMut`!")
393 }
394 }
395
396 fn into_owned(value: Self::Owned) -> Self::Type {
397 value.consume().ok().unwrap()
398 }
399
400 fn into_ref(value: &Self::Ref) -> Self::Borrow<'_> {
401 value.read().unwrap()
402 }
403
404 fn into_ref_mut(value: &mut Self::RefMut) -> Self::BorrowMut<'_> {
405 value.write().unwrap()
406 }
407}
408
409pub enum ManagedValueDependency {
413 Ref(LifetimeRef),
415 RefMut(LifetimeRefMut),
417}
418
419impl<T> ValueDependency<Managed<T>> for ManagedValueDependency {
420 fn as_ref(value: &Managed<T>) -> Self {
421 Self::Ref(value.lifetime().borrow().unwrap())
422 }
423
424 fn as_ref_mut(value: &mut Managed<T>) -> Self {
425 Self::RefMut(value.lifetime().borrow_mut().unwrap())
426 }
427}
428
429impl<T> ValueDependency<ManagedRef<T>> for ManagedValueDependency {
430 fn as_ref(value: &ManagedRef<T>) -> Self {
431 Self::Ref(value.lifetime().borrow().unwrap())
432 }
433
434 fn as_ref_mut(_: &mut ManagedRef<T>) -> Self {
435 panic!("Cannot borrow lifetime mutably from `ManagedRef`!");
436 }
437}
438
439impl<T> ValueDependency<ManagedRefMut<T>> for ManagedValueDependency {
440 fn as_ref(value: &ManagedRefMut<T>) -> Self {
441 Self::Ref(value.lifetime().borrow().unwrap())
442 }
443
444 fn as_ref_mut(value: &mut ManagedRefMut<T>) -> Self {
445 Self::RefMut(value.lifetime().borrow_mut().unwrap())
446 }
447}
448
449impl ValueDependency<DynamicManaged> for ManagedValueDependency {
450 fn as_ref(value: &DynamicManaged) -> Self {
451 Self::Ref(value.lifetime().borrow().unwrap())
452 }
453
454 fn as_ref_mut(value: &mut DynamicManaged) -> Self {
455 Self::RefMut(value.lifetime().borrow_mut().unwrap())
456 }
457}
458
459impl ValueDependency<DynamicManagedRef> for ManagedValueDependency {
460 fn as_ref(value: &DynamicManagedRef) -> Self {
461 Self::Ref(value.lifetime().borrow().unwrap())
462 }
463
464 fn as_ref_mut(_: &mut DynamicManagedRef) -> Self {
465 panic!("Cannot borrow lifetime mutably from `DynamicManagedRef`!");
466 }
467}
468
469impl ValueDependency<DynamicManagedRefMut> for ManagedValueDependency {
470 fn as_ref(value: &DynamicManagedRefMut) -> Self {
471 Self::Ref(value.lifetime().borrow().unwrap())
472 }
473
474 fn as_ref_mut(value: &mut DynamicManagedRefMut) -> Self {
475 Self::RefMut(value.lifetime().borrow_mut().unwrap())
476 }
477}
478
479#[cfg(test)]
480mod tests {
481 use super::*;
482 use crate::{self as intuicio_core, IntuicioStruct, context::Context, define_native_struct};
483 use intuicio_derive::*;
484
485 #[intuicio_function(transformer = "ManagedValueTransformer")]
486 fn add(a: &i32, b: &mut i32) -> i32 {
487 *a + *b
488 }
489
490 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
491 fn sub(a: &i32, b: &mut i32) -> i32 {
492 *a - *b
493 }
494
495 #[intuicio_function(transformer = "ManagedGcValueTransformer")]
496 fn mul(a: &i32, b: &mut i32) -> i32 {
497 *a * *b
498 }
499
500 #[intuicio_function(transformer = "DynamicManagedGcValueTransformer")]
501 fn div(a: &i32, b: &mut i32) -> i32 {
502 *a / *b
503 }
504
505 #[derive(IntuicioStruct, Default, Clone)]
506 #[intuicio(name = "Foo")]
507 struct Foo {
508 bar: i32,
509 }
510
511 #[intuicio_methods(transformer = "ManagedValueTransformer")]
512 impl Foo {
513 #[intuicio_method()]
514 fn new(bar: i32) -> Foo {
515 Foo { bar }
516 }
517
518 #[intuicio_method(dependency = "this")]
519 fn get(&self) -> &i32 {
520 &self.bar
521 }
522
523 #[intuicio_method(dependency = "this")]
524 fn get_mut(&mut self) -> &mut i32 {
525 &mut self.bar
526 }
527 }
528
529 #[derive(IntuicioStruct, Debug, Default, Clone)]
530 #[intuicio(name = "Bar")]
531 struct Bar {
532 foo: i32,
533 }
534
535 #[intuicio_methods(transformer = "DynamicManagedValueTransformer")]
536 impl Bar {
537 #[intuicio_method()]
538 fn new(foo: i32) -> Bar {
539 Bar { foo }
540 }
541
542 #[intuicio_method(dependency = "this")]
543 fn get(&self) -> &i32 {
544 &self.foo
545 }
546 }
547
548 #[test]
549 fn test_derive() {
550 let mut registry = Registry::default().with_basic_types();
551 registry.add_type(define_native_struct! {
552 registry => struct (Managed<Foo>) {}
553 });
554 registry.add_type(define_native_struct! {
555 registry => struct (ManagedRef<Foo>) {}
556 [uninitialized]
557 });
558 registry.add_type(define_native_struct! {
559 registry => struct (ManagedRefMut<Foo>) {}
560 [uninitialized]
561 });
562 registry.add_type(define_native_struct! {
563 registry => struct (Managed<i32>) {}
564 });
565 registry.add_type(define_native_struct! {
566 registry => struct (DynamicManaged) {}
567 [uninitialized]
568 });
569 registry.add_type(define_native_struct! {
570 registry => struct (ManagedRef<i32>) {}
571 [uninitialized]
572 });
573 registry.add_type(define_native_struct! {
574 registry => struct (DynamicManagedRef) {}
575 [uninitialized]
576 });
577 registry.add_type(define_native_struct! {
578 registry => struct (ManagedRefMut<i32>) {}
579 [uninitialized]
580 });
581 registry.add_type(define_native_struct! {
582 registry => struct (DynamicManagedRefMut) {}
583 [uninitialized]
584 });
585 registry.add_type(define_native_struct! {
586 registry => struct (ManagedGc<i32>) {}
587 });
588 registry.add_type(define_native_struct! {
589 registry => struct (DynamicManagedGc) {}
590 [uninitialized]
591 });
592 registry.add_type(Foo::define_struct(®istry));
593 registry.add_function(Foo::new__define_function(®istry));
594 registry.add_type(Bar::define_struct(®istry));
595 registry.add_function(Bar::new__define_function(®istry));
596 let mut context = Context::new(10240, 10240);
597
598 let a = Managed::new(40);
599 let mut b = Managed::new(2);
600 context.stack().push(b.borrow_mut().unwrap());
601 context.stack().push(a.borrow().unwrap());
602 add::intuicio_function(&mut context, ®istry);
603 assert_eq!(
604 context
605 .stack()
606 .pop::<Managed<i32>>()
607 .unwrap()
608 .consume()
609 .ok()
610 .unwrap(),
611 42
612 );
613 assert_eq!(
614 add::define_function(®istry)
615 .call::<(Managed<i32>,), _>(
616 &mut context,
617 ®istry,
618 (a.borrow().unwrap(), b.borrow_mut().unwrap()),
619 true
620 )
621 .0
622 .consume()
623 .ok()
624 .unwrap(),
625 42
626 );
627 assert_eq!(add(&40, &mut 2), 42);
628
629 let a = DynamicManaged::new(40).unwrap();
630 let mut b = DynamicManaged::new(2).unwrap();
631 context.stack().push(b.borrow_mut().unwrap());
632 context.stack().push(a.borrow().unwrap());
633 sub::intuicio_function(&mut context, ®istry);
634 assert_eq!(
635 context
636 .stack()
637 .pop::<DynamicManaged>()
638 .unwrap()
639 .consume::<i32>()
640 .ok()
641 .unwrap(),
642 38
643 );
644 assert_eq!(
645 sub::define_function(®istry)
646 .call::<(DynamicManaged,), _>(
647 &mut context,
648 ®istry,
649 (a.borrow().unwrap(), b.borrow_mut().unwrap()),
650 true
651 )
652 .0
653 .consume::<i32>()
654 .ok()
655 .unwrap(),
656 38
657 );
658 assert_eq!(sub(&40, &mut 2), 38);
659
660 let a = ManagedGc::new(40);
661 let mut b = ManagedGc::new(2);
662 context.stack().push(b.borrow_mut::<false>());
663 context.stack().push(a.borrow::<false>());
664 mul::intuicio_function(&mut context, ®istry);
665 assert_eq!(
666 *context
667 .stack()
668 .pop::<ManagedGc<i32>>()
669 .unwrap()
670 .try_read()
671 .unwrap(),
672 80
673 );
674 assert_eq!(
675 *mul::define_function(®istry)
676 .call::<(ManagedGc<i32>,), _>(
677 &mut context,
678 ®istry,
679 (a.borrow::<false>(), b.borrow_mut::<false>()),
680 true
681 )
682 .0
683 .try_read()
684 .unwrap(),
685 80
686 );
687 assert_eq!(mul(&40, &mut 2), 80);
688
689 let a = DynamicManagedGc::new(40);
690 let mut b = DynamicManagedGc::new(2);
691 context.stack().push(b.borrow_mut::<false>());
692 context.stack().push(a.borrow::<false>());
693 div::intuicio_function(&mut context, ®istry);
694 assert_eq!(
695 *context
696 .stack()
697 .pop::<DynamicManagedGc>()
698 .unwrap()
699 .try_read::<i32>()
700 .unwrap(),
701 20
702 );
703 assert_eq!(
704 *div::define_function(®istry)
705 .call::<(DynamicManagedGc,), _>(
706 &mut context,
707 ®istry,
708 (a.borrow::<false>(), b.borrow_mut::<false>()),
709 true
710 )
711 .0
712 .try_read::<i32>()
713 .unwrap(),
714 20
715 );
716 assert_eq!(div(&40, &mut 2), 20);
717
718 let foo = Managed::new(Foo::new(42));
719 context.stack().push(foo.borrow().unwrap());
720 Foo::get__intuicio_function(&mut context, ®istry);
721 assert_eq!(
722 *context
723 .stack()
724 .pop::<ManagedRef<i32>>()
725 .unwrap()
726 .read()
727 .unwrap(),
728 42
729 );
730 assert_eq!(
731 *Foo::get__define_function(®istry)
732 .call::<(ManagedRef<i32>,), _>(
733 &mut context,
734 ®istry,
735 (foo.borrow().unwrap(),),
736 true
737 )
738 .0
739 .read()
740 .unwrap(),
741 42
742 );
743 assert_eq!(*Foo::new(42).get(), 42);
744
745 let mut foo = Managed::new(Foo::new(42));
746 context.stack().push(foo.borrow_mut().unwrap());
747 Foo::get_mut__intuicio_function(&mut context, ®istry);
748 {
749 let mut result = context.stack().pop::<ManagedRefMut<i32>>().unwrap();
750 let mut result = result.write().unwrap();
751 assert_eq!(*result, 42);
752 *result = 10;
753 }
754 assert_eq!(foo.read().unwrap().bar, 10);
755
756 let bar = DynamicManaged::new(Bar::new(42)).unwrap();
757 context.stack().push(bar.borrow().unwrap());
758 Bar::get__intuicio_function(&mut context, ®istry);
759 assert_eq!(
760 *context
761 .stack()
762 .pop::<DynamicManagedRef>()
763 .unwrap()
764 .read::<i32>()
765 .unwrap(),
766 42
767 );
768 assert_eq!(
769 *Bar::get__define_function(®istry)
770 .call::<(DynamicManagedRef,), _>(
771 &mut context,
772 ®istry,
773 (bar.borrow().unwrap(),),
774 true
775 )
776 .0
777 .read::<i32>()
778 .unwrap(),
779 42
780 );
781 assert_eq!(*Bar::new(42).get(), 42);
782 }
783
784 #[test]
785 fn test_shared_value_transformer() {
786 fn add_wrapped(
787 a: <SharedValueTransformer<i32> as ValueTransformer>::Ref,
788 mut b: <SharedValueTransformer<i32> as ValueTransformer>::RefMut,
789 ) -> <SharedValueTransformer<i32> as ValueTransformer>::Owned {
790 let a = SharedValueTransformer::into_ref(&a);
791 let mut b = SharedValueTransformer::into_ref_mut(&mut b);
792 let result = {
793 let a = &a;
794 let b = &mut b;
795 add(a, b)
796 };
797 let registry = Registry::default();
798 SharedValueTransformer::from_owned(®istry, result)
799 }
800
801 assert_eq!(
802 add(&40, &mut 2),
803 *add_wrapped(Shared::new(40), Shared::new(2)).read().unwrap(),
804 );
805
806 fn get_wrapped(
807 foo: <SharedValueTransformer<Foo> as ValueTransformer>::Ref,
808 ) -> <SharedValueTransformer<i32> as ValueTransformer>::Ref {
809 let foo = SharedValueTransformer::into_ref(&foo);
810 let result = {
811 let foo = &foo;
812 Foo::get(foo)
813 };
814 let registry = Registry::default();
815 SharedValueTransformer::from_ref(®istry, result, None)
816 }
817
818 let foo = Shared::new(Foo { bar: 42 });
819 let a = *Foo::get(&foo.read().unwrap());
820 let b = *get_wrapped(foo.clone()).read().unwrap();
821 assert_eq!(a, b,);
822 }
823
824 #[test]
825 fn test_managed_value_transformer() {
826 fn add_wrapped(
827 a: <ManagedValueTransformer<i32> as ValueTransformer>::Ref,
828 mut b: <ManagedValueTransformer<i32> as ValueTransformer>::RefMut,
829 ) -> <ManagedValueTransformer<i32> as ValueTransformer>::Owned {
830 let a = ManagedValueTransformer::into_ref(&a);
831 let mut b = ManagedValueTransformer::into_ref_mut(&mut b);
832 let result = {
833 let a = &a;
834 let b = &mut b;
835 add(a, b)
836 };
837 let registry = Registry::default();
838 ManagedValueTransformer::from_owned(®istry, result)
839 }
840
841 let a = Managed::new(40);
842 let mut b = Managed::new(2);
843 assert_eq!(
844 add(&40, &mut 2),
845 *add_wrapped(a.borrow().unwrap(), b.borrow_mut().unwrap())
846 .read()
847 .unwrap(),
848 );
849
850 fn get_wrapped(
851 foo: <ManagedValueTransformer<Foo> as ValueTransformer>::Ref,
852 ) -> <ManagedValueTransformer<i32> as ValueTransformer>::Ref {
853 let dependency =
854 Some(<ManagedValueTransformer<i32> as ValueTransformer>::Dependency::as_ref(&foo));
855 let foo = ManagedValueTransformer::into_ref(&foo);
856 let result = {
857 let foo = &foo;
858 Foo::get(foo)
859 };
860 let registry = Registry::default();
861 ManagedValueTransformer::from_ref(®istry, result, dependency)
862 }
863
864 let foo = Managed::new(Foo { bar: 42 });
865 let a = *Foo::get(&foo.read().unwrap());
866 let b = *get_wrapped(foo.borrow().unwrap()).read().unwrap();
867 assert_eq!(a, b,);
868 }
869}