chiark / gitweb /
changelog: document further make-release changes
[otter.git] / support / debugmutex.rs
1
2 use crate::prelude::*;
3
4 #[derive(Debug, Default)]
5 pub struct Mutex<T>(parking_lot::Mutex<T>);
6
7 #[derive(Debug, Display)]
8 pub struct MutexGuard<'g, T>(parking_lot::MutexGuard<'g, T>)
9 where T: DebugIdentify;
10
11 impl<T> Mutex<T> where T: DebugIdentify {
12   pub fn new(t: T) -> Self {
13     Mutex(parking_lot::Mutex::new(t))
14   }
15   pub fn lock(&self) -> MutexGuard<T> {
16     dbg!(dtype::<T>());
17     let r = MutexGuard(self.0.lock());
18     dbg!(dident(&*r));
19     r
20   }
21 }
22
23 impl<'g,T> Deref for MutexGuard<'g,T> where T: DebugIdentify {
24   type Target = T;
25   fn deref(&self) -> &T { &*self.0 }
26 }
27 impl<'g,T> DerefMut for MutexGuard<'g,T> where T: DebugIdentify {
28   fn deref_mut(&mut self) -> &mut T { &mut *self.0 }
29 }
30
31 impl<'g,T> Drop for MutexGuard<'g,T> where T: DebugIdentify {
32   fn drop(&mut self) {
33     dbg!(dident(&**self));
34   }
35 }
36
37 pub fn dtype<T: DebugIdentify>() -> impl Debug {
38   DebugFormatter(T::debug_identify_type)
39 }
40 pub fn dident<'t, T: DebugIdentify>(t: &'t T) -> impl Debug + 't {
41   DebugFormatter(move |f: &'_ mut fmt::Formatter<'_>| t.debug_identify(f))
42 }
43
44 pub struct DebugFormatter<C>(C);
45 impl<C> Debug for DebugFormatter<C>
46 where C: for<'f,'ff> Fn(&'f mut fmt::Formatter<'ff>) -> fmt::Result {
47   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0(f) }
48 }
49
50 pub struct DebugDebugIdentify<'t,T>(&'t T) where T: DebugIdentify;
51 impl<T> Debug for DebugDebugIdentify<'_,T> where T: DebugIdentify {
52   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53     self.0.debug_identify(f)
54   }
55 }
56
57 pub trait DebugIdentify {
58   fn debug_identify_type(f: &mut fmt::Formatter) -> fmt::Result;
59   fn debug_identify(&self, f: &mut fmt::Formatter) -> fmt::Result {
60     Self::debug_identify_type(f)?;
61     write!(f, "({:?})", self as *const _)?;
62     Ok(())
63   }
64 }
65
66 impl<T> DebugIdentify for Option<T> where T: DebugIdentify {
67   #[throws(fmt::Error)]
68   fn debug_identify_type(f: &mut fmt::Formatter) {
69     write!(f, "Option<{:?}>", DebugFormatter(T::debug_identify_type))?;
70   }
71
72   #[throws(fmt::Error)]
73   fn debug_identify(&self, f: &mut fmt::Formatter) {
74     match self {
75       None => write!(f, "None<{:?}>", DebugFormatter(T::debug_identify_type))?,
76       Some(t) => t.debug_identify(f)?,
77     }
78   }
79 }
80
81 impl<T> DebugIdentify for VecDeque<T> where T: DebugIdentify {
82   #[throws(fmt::Error)]
83   fn debug_identify_type(f: &mut fmt::Formatter) {
84     write!(f, "VecDeque<{:?}>", DebugFormatter(T::debug_identify_type))?;
85   }
86 }
87
88 impl DebugIdentify for File{
89   #[throws(fmt::Error)]
90   fn debug_identify_type(f: &mut fmt::Formatter) {
91     write!(f, "File")?;
92   }
93
94   #[throws(fmt::Error)]
95   fn debug_identify(&self, f: &mut fmt::Formatter) {
96     write!(f, "File({})", self.as_raw_fd())?;
97   }
98 }