logicsim/data_structures/
immutable.rs

1use std::ops::Deref;
2
3/// Data structure that enforces immutability at compile time.
4///
5/// It implements [Deref] so all operations on the underlying type will
6/// work as normal, as long as they take an immutable reference.
7///
8/// # Examples
9///
10/// This does not compile:
11/// ```compile_fail
12/// # use logicsim::data_structures::Immutable;
13/// let v = Immutable::new(vec![1,2]);
14///
15/// v.push(2);
16///
17/// ```
18///
19/// This does compile:
20/// ```
21/// # use logicsim::data_structures::Immutable;
22/// let v = Immutable::new(vec![1,2]);
23///
24/// assert_eq!(v[0], 1);
25///
26/// ```
27#[repr(transparent)]
28pub struct Immutable<T>(T);
29impl<T> Immutable<T> {
30    /// Returns a new [Immutable] containing `value`.
31    pub fn new(value: T) -> Self {
32        Self(value)
33    }
34    #[inline(always)]
35    fn get_immutable(&self) -> &T {
36        &self.0
37    }
38}
39
40impl<T> From<T> for Immutable<T> {
41    fn from(i: T) -> Self {
42        Self(i)
43    }
44}
45
46impl<T> Deref for Immutable<T> {
47    type Target = T;
48    fn deref(&self) -> &Self::Target {
49        self.get_immutable()
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    // TODO add failing test if this goes anywhere.
58    // https://github.com/rust-lang/rust/issues/12335.
59    #[test]
60    fn test_immutable() {
61        let i = Immutable::new(vec![1, 2, 3]);
62
63        assert_eq!(i[2], 3);
64    }
65}