swctx 0.3.0

One-shot channel with some special semantics.
Documentation
use std::thread;

use swctx::{mkpair, Error};

#[derive(Clone, Debug, Default, PartialEq)]
enum State {
  #[default]
  Abort,
  NoReply
}

// Trigger an abortion error before wait is called (hopefully).
#[test]
fn abort_before_wait() {
  let (sctx, wctx) = mkpair::<(), State, ()>();

  let jh = thread::spawn(move || {
    let _sctx2 = sctx;
  });
  // join() ensures that SetCtx has been prematurely dropped
  jh.join().unwrap();

  assert_eq!(wctx.wait(), Err(Error::Aborted(State::Abort)));
}

// Trigger an abortion error after wait is called (hopefully).
#[test]
fn abort_after_wait() {
  let (sctx, wctx) = mkpair::<(), State, ()>();

  let jh = thread::spawn(move || {
    // yolo assume 500ms is sufficient
    std::thread::sleep(std::time::Duration::from_millis(500));
    let _sctx2 = sctx;
  });

  assert_eq!(wctx.wait(), Err(Error::Aborted(State::Abort)));

  jh.join().unwrap();
}

// Trigger a no-reply error before wait is called (hopefully).
#[test]
fn noreply_before_wait() {
  let (sctx, wctx) = mkpair::<(), State, ()>();

  let jh = thread::spawn(move || {
    sctx.set_state(State::NoReply).unwrap();
  });
  jh.join().unwrap();

  assert_eq!(wctx.wait(), Err(Error::Aborted(State::NoReply)));
}

// Trigger an no-reply error after wait is called (hopefully).
#[test]
fn noreply_after_wait() {
  let (sctx, wctx) = mkpair::<(), State, ()>();

  let jh = thread::spawn(move || {
    sctx.set_state(State::NoReply).unwrap();
    std::thread::sleep(std::time::Duration::from_millis(500));
  });

  assert_eq!(wctx.wait(), Err(Error::Aborted(State::NoReply)));

  jh.join().unwrap();
}

// Trigger an no-reply error before wait is called (hopefully).
#[test]
fn apperr_before_wait() {
  let (sctx, wctx) = mkpair::<(), State, &str>();

  let jh = thread::spawn(move || {
    sctx.fail("yikes").unwrap();
  });
  jh.join().unwrap();

  assert_eq!(wctx.wait(), Err(Error::App("yikes")));
}

// Trigger an no-reply error after wait is called (hopefully).
#[test]
fn apperr_after_wait() {
  let (sctx, wctx) = mkpair::<(), State, &str>();

  let jh = thread::spawn(move || {
    std::thread::sleep(std::time::Duration::from_millis(500));
    sctx.fail("yikes").unwrap();
  });

  assert_eq!(wctx.wait(), Err(Error::App("yikes")));

  jh.join().unwrap();
}

#[test]
fn lost_waiter() {
  let (sctx, wctx) = mkpair::<(), State, &str>();
  drop(wctx);
  assert_eq!(sctx.set_state(State::Abort), Err(Error::LostWaiter));
  assert_eq!(sctx.set(()), Err(Error::LostWaiter));
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :