use futures::*;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::task::{Context, Poll};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AsyncState {
#[serde(skip)]
value_is_ready: Arc<AtomicBool>,
}
impl Future for AsyncState {
type Output = bool;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.is_ready() {
Poll::Ready(true)
} else {
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
impl Default for AsyncState {
fn default() -> Self {
AsyncState::new()
}
}
impl AsyncState {
pub fn new() -> Self {
AsyncState {
value_is_ready: Arc::new(AtomicBool::new(false)),
}
}
pub fn is_ready(&self) -> bool {
self.value_is_ready.deref().load(Ordering::Relaxed)
}
pub fn set_is_ready(&self, flag: bool) {
self.value_is_ready.store(flag, Ordering::Relaxed)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::{thread, time};
#[actix_rt::test]
async fn asyncstate() {
let my_asyncstate = AsyncState::new();
assert_eq!(my_asyncstate.is_ready(), false);
let clone_asyncsatate = my_asyncstate.clone();
let jh = thread::spawn(move || {
thread::sleep(time::Duration::from_secs(1));
clone_asyncsatate.clone().set_is_ready(true);
});
my_asyncstate.clone().await;
assert_eq!(my_asyncstate.is_ready(), true);
let _ = jh.join();
}
}