1use std::cell::UnsafeCell;
2
3#[derive(Debug)]
4pub struct UnsafeMutex<T> {
5 data: UnsafeCell<T>,
6}
7
8impl<T> UnsafeMutex<T> {
9 pub fn new(data: T) -> Self {
10 UnsafeMutex {
11 data: UnsafeCell::new(data),
12 }
13 }
14
15 #[allow(clippy::mut_from_ref)]
16 pub fn lock(&self) -> &mut T {
17 unsafe { &mut *self.data.get() }
18 }
19}
20
21unsafe impl<T: Send> Send for UnsafeMutex<T> {}
22unsafe impl<T: Send> Sync for UnsafeMutex<T> {}
23
24#[cfg(test)]
25mod tests {
26 use super::*;
27
28 #[test]
29 fn new_creates_mutex_with_data() {
30 let mutex = UnsafeMutex::new(42);
31 assert_eq!(*mutex.lock(), 42);
32 }
33
34 #[test]
35 fn lock_returns_mutable_reference() {
36 let mutex = UnsafeMutex::new(String::from("hello"));
37 let data = mutex.lock();
38 data.push_str(" world");
39 assert_eq!(mutex.lock().as_str(), "hello world");
40 }
41
42 #[test]
43 fn debug_format_shows_type_name() {
44 let mutex = UnsafeMutex::new(42);
45 let debug_str = format!("{:?}", mutex);
46 assert!(debug_str.contains("UnsafeMutex"));
47 }
48
49 #[test]
50 fn send_trait_is_implemented() {
51 fn assert_send<T: Send>() {}
52 assert_send::<UnsafeMutex<i32>>();
53 }
54
55 #[test]
56 fn sync_trait_is_implemented() {
57 fn assert_sync<T: Sync>() {}
58 assert_sync::<UnsafeMutex<i32>>();
59 }
60
61 #[test]
62 fn multiple_locks_return_same_data() {
63 let mutex = UnsafeMutex::new(vec![1, 2, 3]);
64 mutex.lock().push(4);
65 assert_eq!(mutex.lock().len(), 4);
66 mutex.lock().pop();
67 assert_eq!(mutex.lock().len(), 3);
68 }
69}