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(®istry));
505 registry.add_function(Foo::new__define_function(®istry));
506 registry.add_type(Bar::define_struct(®istry));
507 registry.add_function(Bar::new__define_function(®istry));
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, ®istry);
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(®istry)
527 .call::<(Managed<i32>,), _>(
528 &mut context,
529 ®istry,
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, ®istry);
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(®istry)
558 .call::<(DynamicManaged,), _>(
559 &mut context,
560 ®istry,
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, ®istry);
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(®istry)
588 .call::<(ManagedBox<i32>,), _>(
589 &mut context,
590 ®istry,
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, ®istry);
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(®istry)
617 .call::<(DynamicManagedBox,), _>(
618 &mut context,
619 ®istry,
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, ®istry);
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(®istry)
644 .call::<(ManagedRef<i32>,), _>(
645 &mut context,
646 ®istry,
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, ®istry);
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(®istry)
671 .call::<(DynamicManagedRef,), _>(
672 &mut context,
673 ®istry,
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(®istry, 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(®istry, 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(®istry, 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(®istry, 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}