serial_test/
serial_file_lock.rs

1use std::panic;
2
3use crate::file_lock::get_locks;
4
5#[doc(hidden)]
6pub fn fs_serial_core(names: Vec<&str>, path: Option<&str>, function: fn()) {
7    let mut locks = get_locks(&names, path);
8    locks.iter_mut().for_each(|lock| lock.start_serial());
9    let res = panic::catch_unwind(function);
10    locks.into_iter().for_each(|lock| lock.end_serial());
11    if let Err(err) = res {
12        panic::resume_unwind(err);
13    }
14}
15
16#[doc(hidden)]
17pub fn fs_serial_core_with_return<E>(
18    names: Vec<&str>,
19    path: Option<&str>,
20    function: fn() -> Result<(), E>,
21) -> Result<(), E> {
22    let mut locks = get_locks(&names, path);
23    locks.iter_mut().for_each(|lock| lock.start_serial());
24    let res = panic::catch_unwind(function);
25    locks.into_iter().for_each(|lock| lock.end_serial());
26    match res {
27        Ok(ret) => ret,
28        Err(err) => {
29            panic::resume_unwind(err);
30        }
31    }
32}
33
34#[doc(hidden)]
35#[cfg(feature = "async")]
36pub async fn fs_async_serial_core_with_return<E>(
37    names: Vec<&str>,
38    path: Option<&str>,
39    fut: impl std::future::Future<Output = Result<(), E>>,
40) -> Result<(), E> {
41    let mut locks = get_locks(&names, path);
42    locks.iter_mut().for_each(|lock| lock.start_serial());
43    let ret: Result<(), E> = fut.await;
44    locks.into_iter().for_each(|lock| lock.end_serial());
45    ret
46}
47
48#[doc(hidden)]
49#[cfg(feature = "async")]
50pub async fn fs_async_serial_core(
51    names: Vec<&str>,
52    path: Option<&str>,
53    fut: impl std::future::Future<Output = ()>,
54) {
55    let mut locks = get_locks(&names, path);
56    locks.iter_mut().for_each(|lock| lock.start_serial());
57    fut.await;
58    locks.into_iter().for_each(|lock| lock.end_serial());
59}
60
61#[cfg(test)]
62mod tests {
63    use std::panic;
64
65    use fslock::LockFile;
66
67    use super::fs_serial_core;
68    use crate::file_lock::path_for_name;
69
70    #[test]
71    fn test_serial() {
72        fs_serial_core(vec!["test"], None, || {});
73    }
74
75    #[test]
76    fn unlock_on_assert_sync_without_return() {
77        let lock_path = path_for_name("serial_unlock_on_assert_sync_without_return");
78        let _ = panic::catch_unwind(|| {
79            fs_serial_core(
80                vec!["serial_unlock_on_assert_sync_without_return"],
81                Some(&lock_path),
82                || {
83                    assert!(false);
84                },
85            )
86        });
87        let mut lockfile = LockFile::open(&lock_path).unwrap();
88        assert!(lockfile.try_lock().unwrap());
89    }
90}