1#![warn(clippy::pedantic, clippy::nursery, clippy::cargo)]
3#![warn(
5 clippy::as_conversions,
6 clippy::clone_on_ref_ptr,
7 clippy::create_dir,
8 clippy::dbg_macro,
9 clippy::decimal_literal_representation,
10 clippy::default_numeric_fallback,
11 clippy::else_if_without_else,
12 clippy::exhaustive_enums,
13 clippy::exhaustive_structs,
14 clippy::exit,
15 clippy::expect_used,
16 clippy::filetype_is_file,
17 clippy::float_arithmetic,
18 clippy::float_cmp_const,
19 clippy::get_unwrap,
20 clippy::if_then_some_else_none,
21 clippy::indexing_slicing,
22 clippy::integer_arithmetic,
23 clippy::integer_division,
24 clippy::let_underscore_must_use,
25 clippy::lossy_float_literal,
26 clippy::map_err_ignore,
27 clippy::mem_forget,
28 clippy::missing_docs_in_private_items,
29 clippy::modulo_arithmetic,
30 clippy::multiple_inherent_impl,
31 clippy::panic,
32 clippy::panic_in_result_fn,
33 clippy::pattern_type_mismatch,
34 clippy::print_stderr,
35 clippy::print_stdout,
36 clippy::rc_buffer,
37 clippy::rest_pat_in_fully_bound_structs,
38 clippy::str_to_string,
39 clippy::string_add,
40 clippy::string_to_string,
41 clippy::todo,
42 clippy::unimplemented,
43 clippy::unnecessary_self_imports,
44 clippy::unneeded_field_pattern,
45 clippy::unreachable,
46 clippy::unwrap_in_result,
47 clippy::unwrap_used,
48 clippy::use_debug,
49 clippy::verbose_file_reads,
50 clippy::wildcard_enum_match_arm
51)]
52#![warn(
54 elided_lifetimes_in_paths,
55 explicit_outlives_requirements,
56 macro_use_extern_crate,
57 meta_variable_misuse,
58 missing_abi,
59 missing_copy_implementations,
60 missing_debug_implementations,
61 missing_docs,
62 non_ascii_idents,
63 noop_method_call,
64 semicolon_in_expressions_from_macros,
65 single_use_lifetimes,
66 trivial_casts,
67 trivial_numeric_casts,
68 unreachable_pub,
69 unsafe_op_in_unsafe_fn,
70 unused_crate_dependencies,
71 unused_extern_crates,
72 unused_import_braces,
73 unused_lifetimes,
74 unused_qualifications,
75 unused_results,
76 variant_size_differences
77)]
78#![warn(
80 rustdoc::missing_crate_level_docs,
81 rustdoc::missing_doc_code_examples,
82 rustdoc::private_doc_tests,
83 rustdoc::invalid_html_tags
84)]
85
86use std::{fmt, ops, pin::Pin, sync};
100
101#[allow(missing_docs, clippy::missing_docs_in_private_items)]
118pub struct Mutex<T: ?Sized>(sync::Mutex<T>);
119
120impl<T: ?Sized> fmt::Debug for Mutex<T>
121where
122 T: fmt::Debug,
123{
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 fmt::Debug::fmt(&self.0, f)
126 }
127}
128
129#[allow(
131 missing_docs,
132 clippy::missing_docs_in_private_items,
133 clippy::missing_errors_doc
134)]
135impl<T> Mutex<T> {
136 pub fn new(t: T) -> Self {
137 Self(sync::Mutex::new(t))
138 }
139
140 pub fn into_inner(self) -> sync::LockResult<T> {
141 self.0.into_inner()
142 }
143}
144
145#[allow(clippy::missing_docs_in_private_items)]
147fn wrap_result<S, T>(f: impl FnOnce(S) -> T, r: sync::LockResult<S>) -> sync::LockResult<T> {
148 match r {
149 Ok(x) => Ok(f(x)),
150 Err(e) => Err(sync::PoisonError::new(f(e.into_inner()))),
151 }
152}
153
154#[allow(clippy::missing_docs_in_private_items)]
156fn wrap_result_try<S, T>(
157 f: impl FnOnce(S) -> T,
158 r: sync::TryLockResult<S>,
159) -> sync::TryLockResult<T> {
160 use sync::TryLockError::{Poisoned, WouldBlock};
161 match r {
162 Ok(x) => Ok(f(x)),
163 Err(Poisoned(e)) => Err(Poisoned(sync::PoisonError::new(f(e.into_inner())))),
164 Err(WouldBlock) => Err(WouldBlock),
165 }
166}
167
168#[allow(
170 missing_docs,
171 clippy::missing_docs_in_private_items,
172 clippy::missing_errors_doc
173)]
174impl<T: ?Sized> Mutex<T> {
175 pub fn lock(self: Pin<&Self>) -> sync::LockResult<PinMutexGuard<'_, T>> {
176 wrap_result(
177 |x| unsafe { Pin::new_unchecked(x) },
178 self.get_ref().0.lock(),
179 )
180 }
181
182 pub fn lock_no_pin(&self) -> sync::LockResult<NoPinMutexGuard<'_, T>> {
183 wrap_result(NoPinMutexGuard, self.0.lock())
184 }
185
186 pub fn try_lock(self: Pin<&Self>) -> sync::TryLockResult<PinMutexGuard<'_, T>> {
187 wrap_result_try(
188 |x| unsafe { Pin::new_unchecked(x) },
189 self.get_ref().0.try_lock(),
190 )
191 }
192
193 pub fn try_lock_no_pin(&self) -> sync::TryLockResult<NoPinMutexGuard<'_, T>> {
194 wrap_result_try(NoPinMutexGuard, self.0.try_lock())
195 }
196
197 pub fn is_poisoned(&self) -> bool {
198 self.0.is_poisoned()
199 }
200
201 pub fn get_mut(self: Pin<&mut Self>) -> sync::LockResult<Pin<&mut T>> {
202 wrap_result(
203 |x| unsafe { Pin::new_unchecked(x) },
204 unsafe { Pin::into_inner_unchecked(self) }.0.get_mut(),
205 )
206 }
207
208 pub fn get_mut_no_pin(&mut self) -> sync::LockResult<&mut T> {
209 self.0.get_mut()
210 }
211}
212
213#[allow(missing_docs, clippy::missing_docs_in_private_items)]
215pub type PinMutexGuard<'a, T> = Pin<sync::MutexGuard<'a, T>>;
216
217#[allow(missing_docs, clippy::missing_docs_in_private_items)]
219pub struct NoPinMutexGuard<'a, T: ?Sized>(sync::MutexGuard<'a, T>);
220
221impl<T: ?Sized> fmt::Debug for NoPinMutexGuard<'_, T>
222where
223 T: fmt::Debug,
224{
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 fmt::Debug::fmt(&**self, f)
227 }
228}
229
230impl<T: ?Sized> fmt::Display for NoPinMutexGuard<'_, T>
231where
232 T: fmt::Display,
233{
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 fmt::Display::fmt(&**self, f)
236 }
237}
238
239impl<T: ?Sized> ops::Deref for NoPinMutexGuard<'_, T> {
240 type Target = T;
241
242 fn deref(&self) -> &T {
243 &self.0
244 }
245}
246
247impl<T: ?Sized> ops::DerefMut for NoPinMutexGuard<'_, T>
248where
249 T: Unpin,
250{
251 fn deref_mut(&mut self) -> &mut T {
252 &mut self.0
253 }
254}