assemble_core/
immutable.rs

1//! Mark a type as immutable.
2//!
3//! Any type that is immutable can not be mutated, even with ownership
4
5use std::ops::Deref;
6use std::sync::Arc;
7
8#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
9pub struct Immutable<T: ?Sized> {
10    value: Arc<T>,
11}
12
13impl<T: ?Sized> Immutable<T> {
14    /// Create a new immutable object from a value without a known size
15    pub fn from_boxed(value: Box<T>) -> Self {
16        let arc: Arc<T> = Arc::from(value);
17        Self { value: arc }
18    }
19
20    /// Create a new immutable object from a value without a known size
21    pub fn from_arc(value: Arc<T>) -> Self {
22        Self { value }
23    }
24}
25
26impl<T> Immutable<T> {
27    /// Create a new immutable object from a value with known size
28    pub fn new(value: T) -> Self {
29        Self {
30            value: Arc::new(value),
31        }
32    }
33}
34
35impl<T: ?Sized> Deref for Immutable<T> {
36    type Target = T;
37
38    fn deref(&self) -> &Self::Target {
39        &*self.value
40    }
41}
42
43impl<T> AsRef<T> for Immutable<T> {
44    fn as_ref(&self) -> &T {
45        self.value.as_ref()
46    }
47}
48
49impl<T: ?Sized> Clone for Immutable<T> {
50    fn clone(&self) -> Self {
51        Immutable::from_arc(self.value.clone())
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use crate::immutable::Immutable;
58
59    #[test]
60    fn use_immutables() {
61        let i1 = Immutable::new(1);
62        let i2 = Immutable::new(2);
63
64        assert!(i1 < i2);
65    }
66
67    #[test]
68    fn create_from_boxed() {
69        let slice: Box<[i32]> = Box::new([1, 2, 3]);
70        let immutable = Immutable::from_boxed(slice);
71        assert_eq!(immutable[1], 2);
72        assert_eq!(&immutable[..], &[1, 2, 3]);
73    }
74}