@@ -10,7 +10,7 @@ use anyhow::Context;
1010use http:: uri;
1111use serde:: de:: Error ;
1212use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
13- use std:: sync:: { Mutex , MutexGuard } ;
13+ use std:: sync:: { Mutex , MutexGuard , RwLock , RwLockReadGuard , RwLockWriteGuard } ;
1414use std:: { borrow:: Cow , ops:: Deref , path:: PathBuf , str:: FromStr } ;
1515
1616pub mod azure_app_services;
@@ -90,6 +90,51 @@ impl<T> MutexExt<T> for Mutex<T> {
9090 }
9191}
9292
93+ /// Extension trait for `RwLock` to provide methods that acquire read/write locks, panicking if
94+ /// the lock is poisoned.
95+ ///
96+ /// Mirrors [`MutexExt`] for `RwLock` so callers avoid `#[allow(clippy::unwrap_used)]` at each
97+ /// lock site.
98+ ///
99+ /// # Examples
100+ ///
101+ /// ```
102+ /// use libdd_common::RwLockExt;
103+ /// use std::sync::{Arc, RwLock};
104+ ///
105+ /// let data = Arc::new(RwLock::new(5));
106+ /// let data_clone = Arc::clone(&data);
107+ ///
108+ /// std::thread::spawn(move || {
109+ /// let mut num = data_clone.write_or_panic();
110+ /// *num += 1;
111+ /// })
112+ /// .join()
113+ /// .expect("Thread panicked");
114+ ///
115+ /// assert_eq!(*data.read_or_panic(), 6);
116+ /// ```
117+ pub trait RwLockExt < T > {
118+ fn read_or_panic ( & self ) -> RwLockReadGuard < ' _ , T > ;
119+ fn write_or_panic ( & self ) -> RwLockWriteGuard < ' _ , T > ;
120+ }
121+
122+ impl < T > RwLockExt < T > for RwLock < T > {
123+ #[ inline( always) ]
124+ #[ track_caller]
125+ fn read_or_panic ( & self ) -> RwLockReadGuard < ' _ , T > {
126+ #[ allow( clippy:: unwrap_used) ]
127+ self . read ( ) . unwrap ( )
128+ }
129+
130+ #[ inline( always) ]
131+ #[ track_caller]
132+ fn write_or_panic ( & self ) -> RwLockWriteGuard < ' _ , T > {
133+ #[ allow( clippy:: unwrap_used) ]
134+ self . write ( ) . unwrap ( )
135+ }
136+ }
137+
93138pub mod header {
94139 #![ allow( clippy:: declare_interior_mutable_const) ]
95140 use http:: { header:: HeaderName , HeaderValue } ;
0 commit comments