1use core::borrow::{Borrow, BorrowMut};
2use core::cell::Cell;
3use core::ops::{Deref, DerefMut};
4use core::ptr::NonNull;
5
6#[expect(missing_debug_implementations)]
42pub struct Mut<T>(Cell<Option<T>>);
43
44impl<T> From<T> for Mut<T> {
45 fn from(value: T) -> Self {
46 Mut(Cell::new(Some(value)))
47 }
48}
49
50impl<T> Clone for Mut<T> {
51 #[track_caller]
52 fn clone(&self) -> Self {
53 let inner = self.0.replace(None);
54 assert!(inner.is_some(), "magic_args::Mut cloned twice");
55
56 Self(Cell::new(inner))
57 }
58}
59
60impl<T> Mut<T> {
61 fn inner_ptr(&self) -> NonNull<Option<T>> {
62 let ptr = self.0.as_ptr();
63 NonNull::new(ptr).expect("Cell::as_ptr should never return null")
64 }
65
66 #[track_caller]
67 fn inner_ref(&self) -> &T {
68 #[expect(unsafe_code)]
71 let value = unsafe { self.inner_ptr().as_ref() };
72 value.as_ref().expect("magic_args::Mut cloned twice")
73 }
74
75 #[track_caller]
76 #[expect(clippy::mut_from_ref)]
77 fn inner_mut(&self) -> &mut T {
78 #[expect(unsafe_code)]
81 let value = unsafe { self.inner_ptr().as_mut() };
82 value.as_mut().expect("magic_args::Mut cloned twice")
83 }
84
85 #[track_caller]
91 pub fn into_inner(self) -> T {
92 #[expect(unsafe_code)]
95 let value = unsafe { self.inner_ptr().as_mut() };
96 value.take().expect("magic_args::Mut cloned twice")
97 }
98}
99
100macro_rules! impl_borrow {
101 ($T:ty) => {
102 impl<T> Borrow<T> for Mut<$T> {
103 #[inline]
104 fn borrow(&self) -> &T {
105 self.inner_ref()
106 }
107 }
108
109 impl<T> BorrowMut<T> for Mut<$T> {
110 #[inline]
111 fn borrow_mut(&mut self) -> &mut T {
112 self.inner_mut()
113 }
114 }
115 };
116}
117
118macro_rules! impl_as_ref {
119 ($T:ty) => {
120 impl<T> AsRef<T> for Mut<$T> {
121 #[inline]
122 fn as_ref(&self) -> &T {
123 self.inner_ref()
124 }
125 }
126
127 impl<T> AsMut<T> for Mut<$T> {
128 #[inline]
129 fn as_mut(&mut self) -> &mut T {
130 self.inner_mut()
131 }
132 }
133 };
134}
135
136impl_borrow!(T);
137impl_borrow!(&mut T);
138impl_borrow!(&mut &mut T);
139impl_borrow!(&mut &mut &mut T);
140
141impl_as_ref!(T);
142impl_as_ref!(&mut T);
143impl_as_ref!(&mut &mut T);
144impl_as_ref!(&mut &mut &mut T);
145
146impl<T> Deref for Mut<T> {
147 type Target = T;
148
149 #[inline]
150 fn deref(&self) -> &Self::Target {
151 self.inner_ref()
152 }
153}
154
155impl<T> DerefMut for Mut<T> {
156 #[inline]
157 fn deref_mut(&mut self) -> &mut Self::Target {
158 self.inner_mut()
159 }
160}
161
162#[cfg(test)]
165mod tests {
166 use super::*;
167
168 use crate::apply;
169
170 #[test]
171 fn test_mut() {
172 fn f0(_a: i32, b: Mut<i32>) -> i32 {
173 *b
174 }
175
176 fn f1(_a: i32, mut b: Mut<&mut i32>) -> i32 {
177 let b = b.borrow_mut();
178 *b
179 }
180
181 fn f2(_a: i32, mut b: Mut<&mut &mut i32>) -> i32 {
182 let b = b.borrow_mut();
183 *b
184 }
185
186 fn f3(_a: i32, mut b: Mut<&mut &mut &mut i32>) -> i32 {
187 let b = b.borrow_mut();
188 *b
189 }
190
191 assert_eq!(apply(f0, (42i32, Mut::from(31i32))), 31);
192 assert_eq!(apply(f1, (42i32, Mut::from(&mut 31i32))), 31);
193 assert_eq!(apply(f2, (42i32, Mut::from(&mut &mut 31i32))), 31);
194 assert_eq!(apply(f3, (42i32, Mut::from(&mut &mut &mut 31i32))), 31);
195 }
196}