polyhorn_core/
reference.rs1use std::cell::{Ref, RefMut};
2use std::marker::PhantomData;
3
4use super::{Link, Weak, WeakReference};
5
6pub struct Reference<T> {
7 instance_id: usize,
8 reference_id: usize,
9 marker: PhantomData<T>,
10}
11
12impl<T> Reference<T>
13where
14 T: 'static,
15{
16 pub(crate) fn new(instance_id: usize, reference_id: usize) -> Reference<T> {
17 Reference {
18 instance_id,
19 reference_id,
20 marker: PhantomData,
21 }
22 }
23
24 pub fn get<'a, L>(&self, link: &'a L) -> Ref<'a, T>
25 where
26 L: Link,
27 {
28 assert_eq!(self.instance_id, link.instance().id);
29
30 Ref::map(link.memory().reference(self.reference_id), |reference| {
31 reference.downcast_ref().unwrap()
32 })
33 }
34
35 pub fn replace<L>(&self, link: &L, value: T) -> T
36 where
37 L: Link,
38 {
39 assert_eq!(self.instance_id, link.instance().id);
40
41 let reference = link.memory().reference_mut(self.reference_id);
42 let mut reference = RefMut::map(reference, |reference| reference.downcast_mut().unwrap());
43 std::mem::replace(&mut reference, value)
44 }
45
46 pub fn apply<L, F, O>(&self, link: &L, op: F) -> O
47 where
48 L: Link,
49 F: FnOnce(&mut T) -> O,
50 {
51 assert_eq!(self.instance_id, link.instance().id);
52
53 let reference = link.memory().reference_mut(self.reference_id);
54 let mut reference = RefMut::map(reference, |reference| reference.downcast_mut().unwrap());
55 op(&mut reference)
56 }
57
58 pub fn weak<L>(self, link: &L) -> WeakReference<L::Platform, T>
59 where
60 L: Link,
61 {
62 assert_eq!(self.instance_id, link.instance().id);
63
64 WeakReference::new(Weak::new(link.instance()), self)
65 }
66}
67
68impl<T> Reference<T>
69where
70 T: Clone + 'static,
71{
72 pub fn cloned<L>(self, link: &L) -> T
73 where
74 L: Link,
75 {
76 assert_eq!(self.instance_id, link.instance().id);
77
78 link.memory()
79 .reference(self.reference_id)
80 .downcast_ref::<T>()
81 .unwrap()
82 .clone()
83 }
84}
85
86impl<T> Reference<T>
87where
88 T: Default + 'static,
89{
90 pub fn take<L>(&self, link: &L) -> T
91 where
92 L: Link,
93 T: Default,
94 {
95 self.replace(link, Default::default())
96 }
97}
98
99impl<T> Clone for Reference<T> {
100 fn clone(&self) -> Self {
101 *self
102 }
103}
104
105impl<T> Copy for Reference<T> {}