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
130
131
132
133
134
135
136
137
//! # `mutable-constant`
//! 
//! This crate provides a smart pointer that allows
//! mutation on immutable values. In most cases, this
//! will behave like a normal smart pointer like `Box`,
//! but it allows mutation internally when Rust would
//! otherwise forbid it.
//! 
//! Doing this is an unsafe operation. You will need
//! to use `unsafe` blocks to use this crate effectively.
//! 
//! ## Example
//! 
//! ```
//! use mutable_constant::Mc;
//! 
//! let mc = Mc::new(42);
//! let mc_ref = mc.as_ref();
//! 
//! assert_eq!(*mc_ref, 42);
//! 
//! unsafe {
//!     *mc.as_defiant_mut() = 43; // This would normally be a compile error
//! }
//! 
//! assert_eq!(*mc_ref, 43);
//! ```

#![warn(missing_docs)]

/// A smart pointer that allows mutation on immutable values.
/// 
/// This uses a `*mut T` internally, so most internal operations
/// are unsafe. However, thanks to Rust's borrowing guarantees,
/// many of these operations are safe when used publicly. The
/// only operation that is not safe is `as_defiant_mut`, which
/// creates a mutable reference in defiance of Rust's rules.
pub struct Mc<T>(*mut T);

impl<T> Mc<T> {
    /// Creates a new `Mc` from a value.
    /// 
    /// # Example
    /// ```
    /// use mutable_constant::Mc;
    /// 
    /// let mc = Mc::new(42);
    /// ```
    pub fn new(t: T) -> Mc<T> {
        Mc(Box::into_raw(Box::new(t)))
    }

    /// Gets a mutable reference to the inner value.
    /// 
    /// # Safety
    /// 
    /// This is unsafe because the mutable reference does
    /// not obey the borrow checker. For example, a mutable
    /// reference to a `Mc` can be created while there is
    /// an immutable reference to the same `Mc`. If you do
    /// not need this specific behavior, use `as_mut` instead.
    /// 
    /// # Example
    /// ```
    /// use mutable_constant::Mc;
    /// 
    /// let mut mc = Mc::new(42);
    /// 
    /// unsafe {
    ///     *mc.as_defiant_mut() = 43;
    /// }
    /// ```
    pub unsafe fn as_defiant_mut(&self) -> &mut T {
        &mut *self.0
    }
}

impl<T> Drop for Mc<T> {
    fn drop(&mut self) {
        unsafe {
            drop(Box::from_raw(self.0));
        }
    }
}

impl<T> AsRef<T> for Mc<T> {
    fn as_ref(&self) -> &T {
        unsafe { &*self.0 }
    }
}

impl<T> AsMut<T> for Mc<T> {
    fn as_mut(&mut self) -> &mut T {
        unsafe { &mut *self.0 }
    }
}

impl<T> std::fmt::Debug for Mc<T>
where
    T: std::fmt::Debug
{
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        unsafe { &*self.0 }.fmt(f)
    }
}

impl<T> std::fmt::Display for Mc<T>
where
    T: std::fmt::Display
{
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        unsafe { &*self.0 }.fmt(f)
    }
}

impl<T> Clone for Mc<T>
where
    T: Clone
{
    fn clone(&self) -> Self {
        Mc::new(unsafe { &*self.0 }.clone())
    }
}

impl<T> std::ops::Deref for Mc<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}

impl<T> std::ops::DerefMut for Mc<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.0 }
    }
}