intuicio_core/
transformer.rs

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