ferrisetw 1.2.0

Basically a KrabsETW rip-off written in Rust
Documentation
use std::sync::mpsc;
use std::sync::mpsc::{RecvTimeoutError, TrySendError};
use std::time::Duration;

#[derive(Clone, Debug, PartialEq)]
pub enum TestKind {
    /// Test will pass if a success has been notified in the test duration
    ExpectSuccess,
    /// Test will pass if no failure has been notified in the test duration
    ExpectNoFailure,
}

#[derive(Clone, Debug)] // mpsc channels are clone-able to be shared between threads
pub struct StatusNotifier {
    kind: TestKind,
    tx: mpsc::SyncSender<()>,
}

impl StatusNotifier {
    pub fn notify_success(&self) {
        if self.kind == TestKind::ExpectSuccess {
            match self.tx.try_send(()) {
                Ok(()) => (),
                Err(TrySendError::Full(_)) => (), // this means we've sent a success signal already, we don't care
                Err(TrySendError::Disconnected(_)) => (), // Receiver disconnected when the test was still running. That's usually expected, since the callback can outlive the function that started the trace
            }
        }
    }

    #[allow(dead_code)]
    pub fn notify_failure(&self) {
        if self.kind == TestKind::ExpectNoFailure {
            match self.tx.try_send(()) {
                Ok(()) => (),
                Err(TrySendError::Full(_)) => (), // this means we've sent a failure signal already, we don't care
                Err(TrySendError::Disconnected(_)) => (), // Receiver disconnected when the test was still running. That's usually expected, since the callback can outlive the function that started the trace
            }
        }
    }
}

#[derive(Debug)]
pub struct Status {
    notifier: StatusNotifier,
    rx: mpsc::Receiver<()>,
}

impl Status {
    pub fn new(kind: TestKind) -> Self {
        let (tx, rx) = mpsc::sync_channel(1);
        Self {
            notifier: StatusNotifier { kind, tx },
            rx,
        }
    }

    pub fn notifier(&self) -> StatusNotifier {
        self.notifier.clone()
    }

    pub fn assert_passed(&self) {
        let timeout = Duration::from_secs(10);

        match self.notifier.kind {
            TestKind::ExpectSuccess => match self.rx.recv_timeout(timeout) {
                Ok(()) => {}
                Err(RecvTimeoutError::Timeout) => {
                    panic!("Test did not pass within the allowed timeout");
                }
                _ => panic!("Should not happen, the sending end has not hung up."),
            },

            TestKind::ExpectNoFailure => match self.rx.recv_timeout(timeout) {
                Ok(()) => {
                    panic!("Test failed within the allowed timeout");
                }
                Err(RecvTimeoutError::Timeout) => {}
                _ => panic!("Should not happen, the sending end has not hung up."),
            },
        }
    }
}