pub struct ImmediateValuePromise<T: Send> { /* private fields */ }
Expand description
A promise which can be easily created and stored.
Introduction
Will spawn a task to resolve the future immediately. No possibility to read out intermediate values or communicate progress.
One can use Option<ImmediateValuePromise<T>>
inside state structs to make this class somewhat lazy.
That may be an option if you don’t need any progress indication or intermediate values.
After the calculation is done, ImmediateValuePromise<T>
can be read out without mutability requirement using
ImmediateValuePromise::get_state
which also yields an ImmediateValueState
but without requiring mut
.
Another useful feature after calculation is finished,
is that you can use ImmediateValuePromise::poll_state_mut
to get a mutable ImmediateValueState
which allows you to take ownership of inner values with ImmediateValueState::take_value
or get a mutable reference
to the inner via ImmediateValueState::get_value_mut
.
Examples
Basic usage
use std::fs::File;
use std::thread;
use std::time::Duration;
use lazy_async_promise::{ImmediateValuePromise, ImmediateValueState};
let mut oneshot_val = ImmediateValuePromise::new(async {
tokio::time::sleep(Duration::from_millis(50)).await;
let test_error_handling = false;
if test_error_handling {
// We can use the ?-operator for most errors in our futures
let _file = File::open("I_DONT_EXIST_ERROR")?;
}
// return the value wrapped in Ok for the result here
Ok(34)
});
assert!(matches!(
oneshot_val.poll_state(),
ImmediateValueState::Updating
));
thread::sleep(Duration::from_millis(100));
let result = oneshot_val.poll_state();
if let ImmediateValueState::Success(val) = result {
assert_eq!(*val, 34);
} else {
unreachable!();
}
Modifying inner values or taking ownership
use std::thread;
use std::time::Duration;
use lazy_async_promise::{DirectCacheAccess, ImmediateValuePromise, ImmediateValueState};
let mut oneshot_val = ImmediateValuePromise::new(async {
Ok(34)
});
thread::sleep(Duration::from_millis(50));
assert!(matches!(
oneshot_val.poll_state(),
ImmediateValueState::Success(_)
));
let result = oneshot_val.poll_state_mut();
// we got the value, take a mutable ref
if let ImmediateValueState::Success(inner) = result {
*inner=32;
}
else {
unreachable!();
}
assert!(result.get_value_mut().is_some());
// take it out
let value = result.take_value();
assert_eq!(value.unwrap(), 32);
Optional laziness
Option<ImmediateValuePromise>
is a nice way to implement laziness with get_or_insert
or get_or_insert_with
. Unfortunately, using these constructs becomes cumbersome.
To ease the pain, we blanket-implement DirectCacheAccess
for any Option<DirectCacheAccess<T>>
.
use std::thread;
use std::time::Duration;
use lazy_async_promise::{DirectCacheAccess, ImmediateValuePromise};
#[derive(Default)]
struct State {
promise: Option<ImmediateValuePromise<i32>>
}
let mut state = State::default();
let promise_ref = state.promise.get_or_insert_with(|| ImmediateValuePromise::new(async {
Ok(34)
}));
promise_ref.poll_state();
thread::sleep(Duration::from_millis(50));
//now let's assume we forgot about our lease already and want to get the value again:
let value_opt = state.promise.as_ref().unwrap().get_value(); // <- dangerous
let value_opt = state.promise.as_ref().and_then(|i| i.get_value()); // <- better, but still ugly
let value_opt = state.promise.get_value(); // <- way nicer!
assert!(value_opt.is_some());
assert_eq!(*value_opt.unwrap(), 34);
Implementations§
source§impl<T: Send + 'static> ImmediateValuePromise<T>
impl<T: Send + 'static> ImmediateValuePromise<T>
sourcepub fn new<U: Future<Output = Result<T, BoxedSendError>> + Send + 'static>(
updater: U
) -> Self
pub fn new<U: Future<Output = Result<T, BoxedSendError>> + Send + 'static>( updater: U ) -> Self
Creator, supply a future which returns Result<T, Box<dyn Error + Send>
. Will be immediately spawned via tokio.
sourcepub fn poll_state(&mut self) -> &ImmediateValueState<T>
pub fn poll_state(&mut self) -> &ImmediateValueState<T>
Poll the state updating the internal state from the running thread if possible, will return the data or error if ready or updating otherwise.
sourcepub fn poll_state_mut(&mut self) -> &mut ImmediateValueState<T>
pub fn poll_state_mut(&mut self) -> &mut ImmediateValueState<T>
Poll the state, return a mutable ref to to the state
sourcepub fn get_state(&self) -> &ImmediateValueState<T>
pub fn get_state(&self) -> &ImmediateValueState<T>
Get the current state without pulling. No mutability required