intuicio_core/
transformer.rs

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