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}