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(®istry));
504 registry.add_function(Foo::new__define_function(®istry));
505 registry.add_type(Bar::define_struct(®istry));
506 registry.add_function(Bar::new__define_function(®istry));
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, ®istry);
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(®istry)
526 .call::<(Managed<i32>,), _>(
527 &mut context,
528 ®istry,
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, ®istry);
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(®istry)
557 .call::<(DynamicManaged,), _>(
558 &mut context,
559 ®istry,
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, ®istry);
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(®istry)
587 .call::<(ManagedBox<i32>,), _>(
588 &mut context,
589 ®istry,
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, ®istry);
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(®istry)
616 .call::<(DynamicManagedBox,), _>(
617 &mut context,
618 ®istry,
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, ®istry);
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(®istry)
643 .call::<(ManagedRef<i32>,), _>(
644 &mut context,
645 ®istry,
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, ®istry);
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(®istry)
670 .call::<(DynamicManagedRef,), _>(
671 &mut context,
672 ®istry,
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(®istry, 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(®istry, 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(®istry, 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(®istry, 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}