1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use ;
/// Defines metadata to be stored alongside the primary item in a
/// [KeyCell](crate::KeyCell).
///
/// # Purpose #
///
/// Metadata is data associated with a particular `KeyCell`. Its
/// primary purpose is to provide references to other `KeyCell`s. If these other
/// `KeyCell`s were instead stored inside the original `KeyCell`, then any
/// access to those would require us to clone them out before use.
///
/// The key constraint on metadata is that it is immutable so long as KeyCell
/// is immutable (e.g. `Rc<KeyCell<_>>`), so it's not possible to mutate
/// metadata. Interior mutability could be used (`RefCell`), but then panics may
/// occur.
///
/// # Examples #
///
/// The following example shows how we will need to clone out `other` because
/// there is no way to access it after we have split `this` into a `&KeyCell<_>`
/// and a `&mut Key`.
///
/// ```
/// use mutcy::{Key, KeyCell, Rw};
/// use std::rc::Rc;
///
/// struct A {
/// other: Rc<KeyCell<i32>>,
/// }
/// # impl mutcy::Meta for A { type Data = (); }
///
/// fn function(this: Rw<A>) {
/// // We require this clone...
/// let other = this.other.clone();
/// // because we can no longer access `this.other`...
/// let (_this, key): (&KeyCell<_>, &mut Key) = Key::split_rw(this);
/// // to increment `other`.
/// *other.rw(key) += 1;
/// }
/// ```
///
/// Metadata solves the issue of requiring clones.
///
/// ```
/// use mutcy::{Key, KeyCell, Meta, Rw};
/// use std::rc::Rc;
///
/// struct A {}
///
/// impl Meta for A {
/// type Data = Rc<KeyCell<i32>>;
/// }
///
/// fn function(this: Rw<A>) {
/// // We don't need to clone anything before splitting...
/// let (input, key) = Key::split_rw(this);
/// // because we can now access the `KeyCell` metadata via `meta`.
/// *input.meta().rw(key) += 1;
/// }
/// ```
impl_attached_common!
)*
};
}
impl_attached_common_generic!
;
}
impl_attached_tuples!