Thunky

Struct Thunky 

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

Implementations§

Source§

impl<T, E> Thunky<T, E>

Source

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

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());
}));
Source

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

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());
}));  
Source

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

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> !Freeze for Thunky<T, E>

§

impl<T, E> !RefUnwindSafe for Thunky<T, E>

§

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

§

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

§

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

§

impl<T, E> !UnwindSafe for Thunky<T, E>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.