mutcy/meta.rs
1use std::{
2 collections::VecDeque,
3 rc::{Rc, Weak},
4};
5
6/// Defines constant metadata to be stored alongside the primary item in a
7/// [KeyCell](crate::KeyCell).
8///
9/// # Purpose #
10///
11/// Metadata is constant data associated with a particular `KeyCell`. Its
12/// primary purpose is to provide references to other `KeyCell`s. If these other
13/// `KeyCell`s were instead stored inside the original `KeyCell`, then any
14/// access to those would require us to clone them out before use.
15///
16/// # Examples #
17///
18/// The following example shows how we will need to clone out `other` because
19/// there is no way to access it after we have split `this` into a `&KeyCell<_>`
20/// and a `&mut Key`.
21///
22/// ```
23/// use mutcy::{Key, KeyCell, KeyMut};
24/// use std::rc::Rc;
25///
26/// struct A {
27/// other: Rc<KeyCell<i32>>,
28/// }
29/// # impl mutcy::Meta for A { type Data = (); }
30///
31/// fn function(this: KeyMut<A>) {
32/// // We require this clone...
33/// let other = this.other.clone();
34/// // because we can no longer access `this`...
35/// let (_this, key) = Key::split(this);
36/// // to increment `other`.
37/// *other.borrow_mut(key) += 1;
38/// }
39/// ```
40///
41/// Metadata solves the issue of requiring clones.
42///
43/// ```
44/// use mutcy::{Key, KeyCell, KeyMut, Meta};
45/// use std::rc::Rc;
46///
47/// struct A {
48/// // ...
49/// }
50///
51/// impl Meta for A {
52/// type Data = Rc<KeyCell<i32>>;
53/// }
54///
55/// fn function(this: KeyMut<A>) {
56/// // We don't need to clone anything before splitting...
57/// let (input, key) = Key::split(this);
58/// // because we can now access the `KeyCell` metadata via `meta`.
59/// *input.meta().borrow_mut(key) += 1;
60/// }
61/// ```
62pub trait Meta {
63 type Data;
64}
65
66macro_rules! impl_attached_common {
67 ($($ty:ty),* $(,)?) => {
68 $(
69 impl Meta for $ty {
70 type Data = ();
71 }
72 )*
73 };
74}
75
76impl_attached_common! {
77 &str,
78 (),
79 String,
80 bool,
81 char,
82 f32, f64,
83 i8, i16, i32, i64, i128,
84 isize,
85 u8, u16, u32, u64, u128,
86 usize,
87}
88
89macro_rules! impl_attached_common_generic {
90 ($($ty:ident<$($generic:ident),*>),* $(,)?) => {
91 $(
92 impl<$($generic),*> Meta for $ty<$($generic),*> {
93 type Data = ();
94 }
95 )*
96 };
97}
98
99impl_attached_common_generic! {
100 Box<T>,
101 Rc<T>,
102 Vec<T>,
103 VecDeque<T>,
104 Weak<T>,
105}
106
107macro_rules! impl_attached_tuples {
108 ($(($($generic:ident),*)),* $(,)?) => {
109 $(
110 impl<$($generic),*> Meta for ($($generic),*,) {
111 type Data = ();
112 }
113 )*
114 };
115}
116
117impl_attached_tuples! {
118 (A),
119 (A, B),
120 (A, B, C),
121 (A, B, C, D),
122 (A, B, C, D, E),
123 (A, B, C, D, E, F),
124}