win-events 0.0.2

A poor attempt to implement WaitForMultipleObjects and the ManualReset, AutoReset and Pulse types
Documentation
use std::error::Error;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, MutexGuard};
use std::time::Duration;

use crate::events::event::{EventHandle, EventState};
use crate::waiters::waiter::{Signaler, WaitList};
use crate::{wait_one, Event};

struct ManualResetEventInfo {
    fired: AtomicBool,
    waiters: WaitList,
}

impl ManualResetEventInfo {
    fn new(init: bool) -> ManualResetEventInfo {
        ManualResetEventInfo {
            fired: AtomicBool::new(init),
            waiters: WaitList::new(),
        }
    }
}

impl EventState for ManualResetEventInfo {
    fn is_set(&self) -> bool {
        self.fired.load(Ordering::Relaxed)
    }

    fn set(&self) {
        self.fired.store(true, Ordering::Relaxed);
        self.waiters.fire()
    }

    fn clear(&self) {
        self.fired.store(false, Ordering::Relaxed);
        self.waiters.clear();
    }

    fn register_signaler(
        &self,
        pos: usize,
        signaler: Arc<dyn Signaler>,
    ) -> Result<(), Box<dyn Error>> {
        if self.is_set() {
            signaler.fire(pos)?;
        }
        self.waiters.register_signaler(pos, signaler)
    }

    fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
        self.waiters.remove_signaler(signaler)
    }

    fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
        Ok(None)
    }

    fn can_consume(&self) -> bool {
        self.fired.load(Ordering::Relaxed)
    }

    fn consume(&self) {}
}

/// A ManualResetEvent
///
/// An event represents a boolean condition that can be waited on until signaled. This allows a
/// thread to block and wait for another thread to set the event. Until the event is manually reset
/// waiting will return immediately.
///
/// # Examples
///
/// ```
/// use std::thread;
/// use std::time::Duration;
/// use win_events::{Event, ManualResetEvent};
///
/// let evt_started = ManualResetEvent::new(false);
/// let evt_started2 = evt_started.clone();
///
/// // spawn a thread and set the cloned event
/// thread::spawn(move|| {
///     evt_started2.set();
/// });
///
/// // Wait for the started event
/// evt_started.wait(Duration::from_millis(100)).unwrap();
/// ```
#[derive(Clone)]
pub struct ManualResetEvent {
    info: Arc<EventHandle>,
}

impl ManualResetEvent {
    /// Creates a new ManualResetEvent and initialized the value.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::ManualResetEvent;
    ///
    /// let evt = ManualResetEvent::new(false);
    /// ```
    pub fn new(init: bool) -> ManualResetEvent {
        let state: Box<dyn EventState> = Box::new(ManualResetEventInfo::new(init));
        ManualResetEvent {
            info: Arc::new(EventHandle::new(state)),
        }
    }

    /// Gets the current state of the event.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::ManualResetEvent;
    ///
    /// let evt = ManualResetEvent::new(true);
    /// assert!(evt.is_set())
    ///  ```
    pub fn is_set(&self) -> bool {
        self.info.is_set()
    }

    /// Sets the event and fires a signal to any threads waiting on the event.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::ManualResetEvent;
    ///
    /// let evt = ManualResetEvent::new(false);
    /// evt.set();
    /// assert!(evt.is_set())
    /// ```
    pub fn set(&self) {
        self.info.set()
    }

    /// Sets the even, causing any waiting threads to receive a signal.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::ManualResetEvent;
    ///
    /// let evt = ManualResetEvent::new(false);
    /// evt.clear();
    /// assert!(!evt.is_set())
    /// ```
    pub fn clear(&self) {
        self.info.clear()
    }
    /// Creates a new ManualResetEvent and initialized the value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::thread::{sleep, spawn};
    /// use std::time::Duration;
    /// use win_events::ManualResetEvent;
    ///
    /// let evt = ManualResetEvent::new(false);
    /// let evt_inner = evt.clone();
    ///
    /// let worker = spawn(move || {
    ///    sleep(Duration::from_millis(3));
    ///    evt_inner.set()
    /// });
    ///
    /// let wait_result = evt.wait(Duration::from_millis(100)).unwrap();
    /// assert!(wait_result)
    /// ```
    pub fn wait(&self, dur: Duration) -> Result<bool, Box<dyn Error>> {
        wait_one(self, dur)
    }
}

impl Event for ManualResetEvent {
    fn handle(&self) -> &Arc<EventHandle> {
        &self.info
    }
}