alopt 1.0.0

a Rust crate providing efficient synchronization primitives that integrate Option into their design.
Documentation
use std::sync::Arc;
use std::thread;

use alopt::alo::thread::{Wom, Worl};

#[test]
fn test_worl_sync() {
    let worl = Worl::<i8>::new(0).set_timeout(500);

    assert_eq!(*worl.read().unwrap(), 0);

    *worl.write().unwrap() += 3;
    assert_eq!(*worl.read().unwrap(), 3);

    worl.clear().unwrap();
    assert!(worl.read().is_err());

    assert_eq!(*worl.set(67).unwrap(), 67);
    assert_eq!(*worl.read().unwrap(), 67);

    worl.write().unwrap().clear();
    assert!(worl.read().is_err());

    worl.set(-1).unwrap();
    assert_eq!(*worl.read().unwrap(), -1);
    worl.write().unwrap().set(-7);
    assert_eq!(*worl.read().unwrap(), -7);

    {
        let worl_guard = worl.read().unwrap();
        worl.read().unwrap();
        assert_eq!(*worl_guard, -7);
    }

    {
        let worl_guard = worl.read().unwrap();
        assert!(worl.write().is_err());
        assert_eq!(*worl_guard, -7);
    }

    {
        let mut worl_guard = worl.write().unwrap();
        assert!(worl.read().is_err());
        assert_eq!(*worl_guard, -7);
        *worl_guard = 42;
    }
    assert_eq!(*worl.read().unwrap(), 42);

    {
        let mut worl_guard = worl.write().unwrap();
        assert!(worl.write().is_err());
        *worl_guard = 54;
    }
    assert_eq!(*worl.read().unwrap(), 54);
}

#[test]
fn test_worl_threaded() {
    use std::time::Duration;

    let worl = Arc::new(Worl::<i8>::new(0).set_timeout(u16::MAX));

    let mut reader_handles = Vec::new();
    for _ in 0..5000 {
        let worl_reader = worl.clone();
        reader_handles.push(thread::spawn(move || {
            thread::sleep(Duration::from_millis(500));
            *worl_reader.read().unwrap()
        }));
    }

    thread::sleep(Duration::from_millis(30));
    *worl.write().unwrap() += 10;

    for handle in reader_handles {
        let value = handle.join().unwrap();
        assert!(value == 0 || value == 10);
    }

    let worl_clear = worl.clone();
    let clear_handle = thread::spawn(move || {
        worl_clear.write().unwrap().clear();
    });
    clear_handle.join().unwrap();

    assert!(worl.read().is_err());

    let worl_set = worl.clone();
    let set_handle = thread::spawn(move || {
        worl_set.set(91).unwrap();
    });
    set_handle.join().unwrap();

    let value = *worl.read().unwrap();
    assert_eq!(value, 91);

    let worl_clear = worl.clone();
    let clear_handle = thread::spawn(move || {
        worl_clear.write().unwrap().clear();
    });
    clear_handle.join().unwrap();

    assert!(worl.read().is_err());

    let worl_set = worl.clone();
    let set_handle = thread::spawn(move || {
        worl_set.set(91).unwrap();
    });
    set_handle.join().unwrap();

    let value = *worl.read().unwrap();
    assert_eq!(value, 91);
}

#[test]
fn test_wom_sync() {
    let mut empty_wom = Wom::<i32>::empty();
    assert!(empty_wom.get_mut().is_err());
    assert!(empty_wom.lock().is_err());

    let mut wom = Wom::new(10);

    {
        let guard = wom.get_mut().unwrap();
        assert_eq!(*guard, 10);
    }

    {
        let guard = wom.get_mut().unwrap();
        *guard = 15;
        assert_eq!(*guard, 15);
    }
    assert_eq!(*wom.get_mut().unwrap(), 15);

    let wom = Wom::new(15);

    {
        let guard = wom.lock().unwrap();
        assert_eq!(*guard, 15);
    }

    {
        let mut guard = wom.lock().unwrap();
        *guard += 5;
    }
    assert_eq!(*wom.lock().unwrap(), 20);

    {
        let guard = wom.lock().unwrap();
        assert!(wom.try_lock().is_err());
        assert_eq!(*guard, 20);
    }

    {
        let guard = wom.set(54).unwrap();
        assert_eq!(*guard, 54);
        guard.clear();
    }
    assert!(wom.lock().is_err());

    {
        let guard = wom.set(63).unwrap();
        let mut val = 230;
        guard.swap(&mut val);
        assert_eq!(val, 63);
        assert_eq!(*guard, 230);
        guard.set(125);
    }
    assert_eq!(*wom.lock().unwrap(), 125);
}

#[test]
fn test_wom_threaded() {
    const THREAD_COUNT: usize = 4;
    const ITERS_PER_THREAD: usize = 1_000;

    let wom = Arc::new(Wom::new(0));
    let mut handles = Vec::with_capacity(THREAD_COUNT);

    for _ in 0..THREAD_COUNT {
        let wom_clone = Arc::clone(&wom);
        let handle = thread::spawn(move || {
            let mut guard = wom_clone.lock().unwrap();
            *guard += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    assert_eq!(*wom.lock().unwrap(), THREAD_COUNT as i32);

    let wom = Arc::new(Wom::new(0));
    let mut handles = Vec::with_capacity(THREAD_COUNT);
    for _ in 0..THREAD_COUNT {
        let m = wom.clone();
        handles.push(thread::spawn(move || {
            for _ in 0..ITERS_PER_THREAD {
                let mut data = m.lock().unwrap();
                *data += 1;
            }
        }));
    }
    for h in handles {
        h.join().unwrap();
    }
}