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
//! # AnyLock Polymorphic Lock Traits
//!
//! Provides a unified interface to different underlying lock implementations.
//!
//! Works as either `RwLock` or `Mutex`. For `Mutex` types, [`AnyLock::read()`] and [`AnyLock::write()`] are aliased.
//!
//! [`AnyLock`] provides newtype wrappers around supported locks:
//!
//! | Provider | Mutex | RwLock |
//! |----------------|---------------------------------|------------------------------|
//! | parking_lot | [`crate::ParkingLotMutex`] | [`crate::ParkingLotRwLock`] |
//! | std::sync | [`crate::StdMutex`] | [`crate::StdRwLock`] |
//! | tokio | [`crate::TokioMutex`] | [`crate::TokioRwLock`] |
//! | core::sync | [`crate::CoreRefCell`] | |
//!
//! ## Async
//! Async locks using [`tokio`] are supported using [`AnyLock::async_read()`] and [`AnyLock::async_write()`].
//!
//! ## Example
//!
//! ```
//! use anylock::AnyLock;
//! use std::{marker::PhantomData, sync::Arc};
//!
//! // Using type annotations, you can use AnyLock::new()
//! let arc_lock_string: Arc<anylock::StdMutex<String>> =
//! Arc::new(AnyLock::new("Hello AnyLock".into()));
//!
//! // Although this is a Mutex, we access it using read() and write()
//! // to allow AnyLock to be compatible with RwLock APIs.
//! println!("{}", arc_lock_string.read());
//!
//! /// Example struct wrapping some inner type T with any kind of lock
//! #[derive(Default)]
//! struct MyWrapper<T, Lock>
//! where
//! // Use a trait bound to accept any kind of lock
//! Lock: AnyLock<T>,
//! {
//! inner: Arc<Lock>,
//! _phantom: PhantomData<T>,
//! }
//!
//! impl<T, Lock> MyWrapper<T, Lock>
//! where
//! Lock: AnyLock<T>,
//! {
//! fn new(inner: T) -> Self {
//! Self {
//! inner: Arc::new(Lock::new(inner)),
//! _phantom: PhantomData,
//! }
//! }
//! }
//!
//! // Now we can create MyWrapper with different locks without modifying
//! // the implementation of MyWrapper itself.
//!
//! // std::Mutex
//! let x = MyWrapper::<String, anylock::StdMutex<_>>::new("Hello".into());
//! println!("{}", x.inner.read());
//!
//! // parking_lot::RwLock
//! let x = MyWrapper::<String, anylock::ParkingLotRwLock<String>>::new("Hello".into());
//!
//! // Acquire write lock and write
//! *x.inner.write() = "World".into();
//!
//! // Acquire read lock and read
//! println!("{:?}", x.inner.read());
//!
//!
//! ```
pub use CoreRefCell;
pub use ;
pub use ;
pub use ;
use ;
/// AnyLock trait allows different underlying lock implementations.
///
///