use crate::import::*;
#[ derive( Clone ) ]
pub struct Progress<State> where State: 'static + Clone + Send + Sync + Eq + fmt::Debug
{
state : Arc<Mutex<State >>,
pharos: Arc<Mutex<Pharos<State>>>,
}
impl<State> Progress<State> where State: 'static + Clone + Send + Sync + Eq + fmt::Debug
{
pub fn new( state: State ) -> Self
{
Self
{
state : Arc::new( Mutex::new( state )) ,
pharos: Arc::new( Mutex::new( Pharos::default() )) ,
}
}
pub async fn set_state( &self, new_state: State )
{
let mut pharos = self.pharos.lock().await;
let mut state = self.state .lock().await;
trace!( "Set progress to: {:?}", new_state );
pharos.send( new_state.clone() ).await.expect( "notify" );
*state = new_state;
}
pub fn current( &self ) -> State
{
block_on( self.state.lock() ).clone()
}
pub fn wait( &self, state: State ) -> Events<State>
{
block_on( async
{
let mut ph = self.pharos.lock().await;
let cl = Filter::Closure( Box::new( move |s| s == &state ) );
ph.observe( cl.into() ).await.expect( "observe" )
})
}
pub fn once( &self, state: State ) -> impl Future + Send
{
let evts =
{
block_on( async
{
let mut ph = self.pharos.lock().await;
let cl = Filter::Closure( Box::new( move |s| s == &state ) );
ph.observe( cl.into() ).await.expect( "observe" )
})
};
async { let _ = evts.into_future().await; }
}
}
impl<State> Observable<State> for Progress<State> where State: 'static + Clone + Send + Sync + Eq + fmt::Debug
{
type Error = pharos::PharErr;
fn observe( &mut self, options: ObserveConfig<State> ) -> Observe< '_, State, Self::Error >
{
async move
{
self.pharos.lock().await.observe( options ).await
}.boxed()
}
}
impl<State> fmt::Debug for Progress<State> where State: 'static + Clone + Send + Sync + Eq + fmt::Debug
{
fn fmt( &self, f: &mut fmt::Formatter<'_> ) -> fmt::Result
{
write!( f, "Progress<{}>", type_name::<State>() )
}
}