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)
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 as intuicio_core;
399    use crate::prelude::*;
400    use intuicio_derive::*;
401
402    #[intuicio_function(transformer = "ManagedValueTransformer")]
403    fn add(a: &i32, b: &mut i32) -> i32 {
404        *a + *b
405    }
406
407    #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
408    fn sub(a: &i32, b: &mut i32) -> i32 {
409        *a - *b
410    }
411
412    #[intuicio_function(transformer = "ManagedBoxValueTransformer")]
413    fn mul(a: &i32, b: &mut i32) -> i32 {
414        *a * *b
415    }
416
417    #[intuicio_function(transformer = "DynamicManagedBoxValueTransformer")]
418    fn div(a: &i32, b: &mut i32) -> i32 {
419        *a / *b
420    }
421
422    #[derive(IntuicioStruct, Default, Clone)]
423    #[intuicio(name = "Foo")]
424    struct Foo {
425        bar: i32,
426    }
427
428    #[intuicio_methods(transformer = "ManagedValueTransformer")]
429    impl Foo {
430        #[intuicio_method()]
431        fn new(bar: i32) -> Foo {
432            Foo { bar }
433        }
434
435        #[intuicio_method(dependency = "this")]
436        fn get(&self) -> &i32 {
437            &self.bar
438        }
439    }
440
441    #[derive(IntuicioStruct, Debug, Default, Clone)]
442    #[intuicio(name = "Bar")]
443    struct Bar {
444        foo: i32,
445    }
446
447    #[intuicio_methods(transformer = "DynamicManagedValueTransformer")]
448    impl Bar {
449        #[intuicio_method()]
450        fn new(foo: i32) -> Bar {
451            Bar { foo }
452        }
453
454        #[intuicio_method(dependency = "this")]
455        fn get(&self) -> &i32 {
456            &self.foo
457        }
458    }
459
460    #[test]
461    fn test_derive() {
462        let mut registry = Registry::default().with_basic_types();
463        registry.add_type(define_native_struct! {
464            registry => struct (Managed<Foo>) {}
465        });
466        registry.add_type(define_native_struct! {
467            registry => struct (ManagedRef<Foo>) {}
468            [uninitialized]
469        });
470        registry.add_type(define_native_struct! {
471            registry => struct (ManagedRefMut<Foo>) {}
472            [uninitialized]
473        });
474        registry.add_type(define_native_struct! {
475            registry => struct (Managed<i32>) {}
476        });
477        registry.add_type(define_native_struct! {
478            registry => struct (DynamicManaged) {}
479            [uninitialized]
480        });
481        registry.add_type(define_native_struct! {
482            registry => struct (ManagedRef<i32>) {}
483            [uninitialized]
484        });
485        registry.add_type(define_native_struct! {
486            registry => struct (DynamicManagedRef) {}
487            [uninitialized]
488        });
489        registry.add_type(define_native_struct! {
490            registry => struct (ManagedRefMut<i32>) {}
491            [uninitialized]
492        });
493        registry.add_type(define_native_struct! {
494            registry => struct (DynamicManagedRefMut) {}
495            [uninitialized]
496        });
497        registry.add_type(define_native_struct! {
498            registry => struct (ManagedBox<i32>) {}
499        });
500        registry.add_type(define_native_struct! {
501            registry => struct (DynamicManagedBox) {}
502            [uninitialized]
503        });
504        registry.add_type(Foo::define_struct(&registry));
505        registry.add_function(Foo::new__define_function(&registry));
506        registry.add_type(Bar::define_struct(&registry));
507        registry.add_function(Bar::new__define_function(&registry));
508        let mut context = Context::new(10240, 10240);
509
510        let a = Managed::new(40);
511        let mut b = Managed::new(2);
512        context.stack().push(b.borrow_mut().unwrap());
513        context.stack().push(a.borrow().unwrap());
514        add::intuicio_function(&mut context, &registry);
515        assert_eq!(
516            context
517                .stack()
518                .pop::<Managed<i32>>()
519                .unwrap()
520                .consume()
521                .ok()
522                .unwrap(),
523            42
524        );
525        assert_eq!(
526            add::define_function(&registry)
527                .call::<(Managed<i32>,), _>(
528                    &mut context,
529                    &registry,
530                    (a.borrow().unwrap(), b.borrow_mut().unwrap()),
531                    true
532                )
533                .0
534                .consume()
535                .ok()
536                .unwrap(),
537            42
538        );
539        assert_eq!(add(&40, &mut 2), 42);
540
541        let a = DynamicManaged::new(40).unwrap();
542        let mut b = DynamicManaged::new(2).unwrap();
543        context.stack().push(b.borrow_mut().unwrap());
544        context.stack().push(a.borrow().unwrap());
545        sub::intuicio_function(&mut context, &registry);
546        assert_eq!(
547            context
548                .stack()
549                .pop::<DynamicManaged>()
550                .unwrap()
551                .consume::<i32>()
552                .ok()
553                .unwrap(),
554            38
555        );
556        assert_eq!(
557            sub::define_function(&registry)
558                .call::<(DynamicManaged,), _>(
559                    &mut context,
560                    &registry,
561                    (a.borrow().unwrap(), b.borrow_mut().unwrap()),
562                    true
563                )
564                .0
565                .consume::<i32>()
566                .ok()
567                .unwrap(),
568            38
569        );
570        assert_eq!(sub(&40, &mut 2), 38);
571
572        let a = ManagedBox::new(40);
573        let mut b = ManagedBox::new(2);
574        context.stack().push(b.borrow_mut().unwrap());
575        context.stack().push(a.borrow().unwrap());
576        mul::intuicio_function(&mut context, &registry);
577        assert_eq!(
578            *context
579                .stack()
580                .pop::<ManagedBox<i32>>()
581                .unwrap()
582                .read()
583                .unwrap(),
584            80
585        );
586        assert_eq!(
587            *mul::define_function(&registry)
588                .call::<(ManagedBox<i32>,), _>(
589                    &mut context,
590                    &registry,
591                    (a.borrow().unwrap(), b.borrow_mut().unwrap()),
592                    true
593                )
594                .0
595                .read()
596                .unwrap(),
597            80
598        );
599        assert_eq!(mul(&40, &mut 2), 80);
600
601        let a = DynamicManagedBox::new(40);
602        let mut b = DynamicManagedBox::new(2);
603        context.stack().push(b.borrow_mut().unwrap());
604        context.stack().push(a.borrow().unwrap());
605        div::intuicio_function(&mut context, &registry);
606        assert_eq!(
607            *context
608                .stack()
609                .pop::<DynamicManagedBox>()
610                .unwrap()
611                .read::<i32>()
612                .unwrap(),
613            20
614        );
615        assert_eq!(
616            *div::define_function(&registry)
617                .call::<(DynamicManagedBox,), _>(
618                    &mut context,
619                    &registry,
620                    (a.borrow().unwrap(), b.borrow_mut().unwrap()),
621                    true
622                )
623                .0
624                .read::<i32>()
625                .unwrap(),
626            20
627        );
628        assert_eq!(div(&40, &mut 2), 20);
629
630        let foo = Managed::new(Foo::new(42));
631        context.stack().push(foo.borrow().unwrap());
632        Foo::get__intuicio_function(&mut context, &registry);
633        assert_eq!(
634            *context
635                .stack()
636                .pop::<ManagedRef<i32>>()
637                .unwrap()
638                .read()
639                .unwrap(),
640            42
641        );
642        assert_eq!(
643            *Foo::get__define_function(&registry)
644                .call::<(ManagedRef<i32>,), _>(
645                    &mut context,
646                    &registry,
647                    (foo.borrow().unwrap(),),
648                    true
649                )
650                .0
651                .read()
652                .unwrap(),
653            42
654        );
655        assert_eq!(*Foo::new(42).get(), 42);
656
657        let bar = DynamicManaged::new(Bar::new(42)).unwrap();
658        context.stack().push(bar.borrow().unwrap());
659        Bar::get__intuicio_function(&mut context, &registry);
660        assert_eq!(
661            *context
662                .stack()
663                .pop::<DynamicManagedRef>()
664                .unwrap()
665                .read::<i32>()
666                .unwrap(),
667            42
668        );
669        assert_eq!(
670            *Bar::get__define_function(&registry)
671                .call::<(DynamicManagedRef,), _>(
672                    &mut context,
673                    &registry,
674                    (bar.borrow().unwrap(),),
675                    true
676                )
677                .0
678                .read::<i32>()
679                .unwrap(),
680            42
681        );
682        assert_eq!(*Bar::new(42).get(), 42);
683    }
684
685    #[test]
686    fn test_shared_value_transformer() {
687        fn add_wrapped(
688            a: <SharedValueTransformer<i32> as ValueTransformer>::Ref,
689            mut b: <SharedValueTransformer<i32> as ValueTransformer>::RefMut,
690        ) -> <SharedValueTransformer<i32> as ValueTransformer>::Owned {
691            let a = SharedValueTransformer::into_ref(&a);
692            let mut b = SharedValueTransformer::into_ref_mut(&mut b);
693            let result = {
694                let a = &a;
695                let b = &mut b;
696                add(a, b)
697            };
698            let registry = Registry::default();
699            SharedValueTransformer::from_owned(&registry, result)
700        }
701
702        assert_eq!(
703            add(&40, &mut 2),
704            *add_wrapped(Shared::new(40), Shared::new(2)).read().unwrap(),
705        );
706
707        fn get_wrapped(
708            foo: <SharedValueTransformer<Foo> as ValueTransformer>::Ref,
709        ) -> <SharedValueTransformer<i32> as ValueTransformer>::Ref {
710            let foo = SharedValueTransformer::into_ref(&foo);
711            let result = {
712                let foo = &foo;
713                Foo::get(foo)
714            };
715            let registry = Registry::default();
716            SharedValueTransformer::from_ref(&registry, result, None)
717        }
718
719        let foo = Shared::new(Foo { bar: 42 });
720        let a = *Foo::get(&foo.read().unwrap());
721        let b = *get_wrapped(foo.clone()).read().unwrap();
722        assert_eq!(a, b,);
723    }
724
725    #[test]
726    fn test_managed_value_transformer() {
727        fn add_wrapped(
728            a: <ManagedValueTransformer<i32> as ValueTransformer>::Ref,
729            mut b: <ManagedValueTransformer<i32> as ValueTransformer>::RefMut,
730        ) -> <ManagedValueTransformer<i32> as ValueTransformer>::Owned {
731            let a = ManagedValueTransformer::into_ref(&a);
732            let mut b = ManagedValueTransformer::into_ref_mut(&mut b);
733            let result = {
734                let a = &a;
735                let b = &mut b;
736                add(a, b)
737            };
738            let registry = Registry::default();
739            ManagedValueTransformer::from_owned(&registry, result)
740        }
741
742        let a = Managed::new(40);
743        let mut b = Managed::new(2);
744        assert_eq!(
745            add(&40, &mut 2),
746            *add_wrapped(a.borrow().unwrap(), b.borrow_mut().unwrap())
747                .read()
748                .unwrap(),
749        );
750
751        fn get_wrapped(
752            foo: <ManagedValueTransformer<Foo> as ValueTransformer>::Ref,
753        ) -> <ManagedValueTransformer<i32> as ValueTransformer>::Ref {
754            let dependency =
755                Some(<ManagedValueTransformer<i32> as ValueTransformer>::Dependency::as_ref(&foo));
756            let foo = ManagedValueTransformer::into_ref(&foo);
757            let result = {
758                let foo = &foo;
759                Foo::get(foo)
760            };
761            let registry = Registry::default();
762            ManagedValueTransformer::from_ref(&registry, result, dependency)
763        }
764
765        let foo = Managed::new(Foo { bar: 42 });
766        let a = *Foo::get(&foo.read().unwrap());
767        let b = *get_wrapped(foo.borrow().unwrap()).read().unwrap();
768        assert_eq!(a, b,);
769    }
770}