[][src]Struct thunky::Thunky

pub struct Thunky<T, E> { /* fields omitted */ }

Methods

impl<T, E> Thunky<T, E>[src]

pub fn new(run: Box<dyn Fn(&Thunky<T, E>) + Send + Sync>) -> Arc<Thunky<T, E>>[src]

Create a thunky instance with a function which take a reference of thunky as parameters,

So we can call thunky.cache() in this function.

Examples

// test: run_only_once
extern crate thunky; 
use thunky::*;
use std::sync::Mutex;

let v = Mutex::new(0);

let run = move |thunk: &Thunky<u32, &str>| {
  *v.lock().unwrap() += 1;
  thunk.cache(Ok(*v.lock().unwrap()));
};

let thunk = Thunky::new(Box::new(run));
 
thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(1, arg.unwrap());
}));

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(1, arg.unwrap());
}));  

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(1, arg.unwrap());
}));

pub fn cache(&self, a: Result<T, E>)[src]

Set cache, if incoming is Ok(T), cahce will be preserved, and ignore the following thunk.cache().

otherwise cache will be reset by next calling to thunk.cache()

Examples

// test: re_run_on_error
  
extern crate thunky;
use std::sync::Mutex;
use thunky::*;


let v = Mutex::new(0);

let run = move |thunk: &Thunky<u32, &str>| {
  *v.lock().unwrap() += 1;

  if *v.lock().unwrap() == 1 {
    thunk.cache(Err("stop"))
  } else if *v.lock().unwrap() == 2 {
    thunk.cache(Err("stop"))
  } else if *v.lock().unwrap() == 3 {
    thunk.cache(Ok(*v.lock().unwrap()))
  } else if *v.lock().unwrap() == 4 {
    thunk.cache(Ok(*v.lock().unwrap()))
  }
};

let thunk = Thunky::new(Box::new(run));
 
thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!("stop", arg.unwrap_err());
}));
 
thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!("stop", arg.unwrap_err());
}));  

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(3, arg.unwrap());
}));    

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(3, arg.unwrap());
}));  

pub fn run(&self, callback: Box<dyn Fn(&Result<T, E>) + Send + Sync>)[src]

Call run() of the current state of thunky. There're three private inner states in thunky:

Run {}: initial state, and after set the cache to Err(E), state turns back to Run.

Wait {}: after call run() of Run, before set the cache, state stays Wait.

Finish {}: after set the cache to Ok(T), state turns to Finish forever.

Examples

// test: run only once async

extern crate thunky;
extern crate tokio;

use std::sync::{ Arc, Mutex };
use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer::Delay;
use thunky::*;  
  
let run = move |_thunk: &Thunky<u32, &str>| {};

let thunk = Thunky::new(Box::new(run));

let v = Mutex::new(0);
let thunk_clone = Arc::clone(&thunk);
let when = Instant::now() + Duration::from_millis(1000);    
let task = Delay::new(when)
  .and_then(move |_| {
    *v.lock().unwrap() += 1;
    thunk_clone.cache(Ok(*v.lock().unwrap()));
    Ok(())
  })
  .map_err(|e| panic!("delay errored; err={:?}", e));  

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(1, arg.unwrap());
}));

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_ne!(2, arg.unwrap());
}));  

thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
  assert_eq!(1, arg.unwrap());
}));

tokio::run(task);  

Auto Trait Implementations

impl<T, E> Send for Thunky<T, E> where
    E: Send,
    T: Send

impl<T, E> Sync for Thunky<T, E> where
    E: Send,
    T: Send

Blanket Implementations

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]