Skip to content

Latest commit

 

History

History
94 lines (69 loc) · 2.38 KB

README.md

File metadata and controls

94 lines (69 loc) · 2.38 KB

thunky

crates.io version build status downloads

Delay the evaluation of a paramless async function and cache the result. Adapted from mafintosh/thunky

Example

Let's make a simple function that returns a random number 1 second after it is called for the first time

extern crate thunky;
extern crate rand;
use thunky::*;
use rand::Rng;

fn main () {
    let run = move |thunk: &Thunky<u32, &str>| {
        let mut rng = rand::thread_rng();
        thunk.cache(Ok(rng.gen::<u32>()));
    };

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

    // I miss JavaScript's `setTimeout()`
    let thunk_clone = Arc::clone(&thunk);
    let when = Instant::now() + Duration::from_millis(1000);
    let task = Delay::new(when)
        .and_then(move |_| {
           let mut rng = rand::thread_rng();
           thunk_clone.cache(Ok(rng.gen::<u32>()));
           Ok(())
        })
        .map_err(|e| panic!("delay errored; err={:?}", e));

    thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
        println!("{}", arg.unwrap()); // prints random number
    }));

    tokio::run(task);  

    thunk.run(Box::new(|arg: &Result<u32, &str>| -> () {
        println!("{}", arg.unwrap()); // prints the same random number as above
    }));
}

Error → No caching

If the thunk cache function is called with an Err<E>, it will not cache the result

let v = Mutex::new(0);

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

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

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

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

Installation

cargo add thunky

License

MIT OR APACHE