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(®istry));
508 registry.add_function(Foo::new__define_function(®istry));
509 registry.add_type(Bar::define_struct(®istry));
510 registry.add_function(Bar::new__define_function(®istry));
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, ®istry);
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(®istry)
530 .call::<(Managed<i32>,), _>(
531 &mut context,
532 ®istry,
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, ®istry);
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(®istry)
561 .call::<(DynamicManaged,), _>(
562 &mut context,
563 ®istry,
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, ®istry);
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(®istry)
591 .call::<(ManagedGc<i32>,), _>(
592 &mut context,
593 ®istry,
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, ®istry);
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(®istry)
620 .call::<(DynamicManagedGc,), _>(
621 &mut context,
622 ®istry,
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, ®istry);
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(®istry)
647 .call::<(ManagedRef<i32>,), _>(
648 &mut context,
649 ®istry,
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, ®istry);
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(®istry)
674 .call::<(DynamicManagedRef,), _>(
675 &mut context,
676 ®istry,
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(®istry, 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(®istry, 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(®istry, 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(®istry, 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}