serial_test/
lib.rs
1use lazy_static::lazy_static;
21use parking_lot::ReentrantMutex;
22use std::collections::HashMap;
23use std::ops::{Deref, DerefMut};
24use std::sync::{Arc, RwLock};
25
26lazy_static! {
27 static ref LOCKS: Arc<RwLock<HashMap<String, ReentrantMutex<()>>>> =
28 Arc::new(RwLock::new(HashMap::new()));
29}
30
31fn check_new_key(name: &str) {
32 let new_key = {
34 let unlock = LOCKS.read().unwrap();
35 !unlock.deref().contains_key(name)
36 };
37 if new_key {
38 LOCKS
40 .write()
41 .unwrap()
42 .deref_mut()
43 .insert(name.to_string(), ReentrantMutex::new(()));
44 }
45}
46
47#[doc(hidden)]
48pub fn serial_core_with_return<E>(name: &str, function: fn() -> Result<(), E>) -> Result<(), E> {
49 check_new_key(name);
50
51 let unlock = LOCKS.read().unwrap();
52 let _guard = unlock.deref()[name].lock();
54 function()
55}
56
57#[doc(hidden)]
58pub fn serial_core(name: &str, function: fn()) {
59 check_new_key(name);
60
61 let unlock = LOCKS.read().unwrap();
62 let _guard = unlock.deref()[name].lock();
64 function();
65}
66
67#[doc(hidden)]
68pub async fn async_serial_core_with_return<E>(
69 name: &str,
70 fut: impl std::future::Future<Output = Result<(), E>>,
71) -> Result<(), E> {
72 check_new_key(name);
73
74 let unlock = LOCKS.read().unwrap();
75 let _guard = unlock.deref()[name].lock();
77 fut.await
78}
79
80#[doc(hidden)]
81pub async fn async_serial_core(name: &str, fut: impl std::future::Future<Output = ()>) {
82 check_new_key(name);
83
84 let unlock = LOCKS.read().unwrap();
85 let _guard = unlock.deref()[name].lock();
87 fut.await
88}
89
90#[allow(unused_imports)]
92pub use serial_test_derive::serial;