use tokio::sync::watch;
use crate::error::Error;
use crate::session::{OneshotReceiver, PersistentReceiver, SessionState, WatchReceiver, WatchedEvent};
#[derive(Clone, Debug)]
pub struct StateWatcher {
receiver: watch::Receiver<SessionState>,
}
impl StateWatcher {
pub(super) fn new(receiver: watch::Receiver<SessionState>) -> StateWatcher {
StateWatcher { receiver }
}
pub fn state(&mut self) -> SessionState {
let state = self.receiver.borrow_and_update();
*state
}
pub async fn changed(&mut self) -> SessionState {
if self.receiver.changed().await.is_err() {
std::future::pending().await
}
self.state()
}
pub fn peek_state(&self) -> SessionState {
let state = self.receiver.borrow();
*state
}
}
#[derive(Debug)]
pub struct OneshotWatcher {
root_len: usize,
receiver: OneshotReceiver,
}
impl OneshotWatcher {
fn new(root_len: usize, receiver: OneshotReceiver) -> Self {
OneshotWatcher { root_len, receiver }
}
pub async fn changed(self) -> WatchedEvent {
let mut event = self.receiver.recv().await;
event.drain_root_len(self.root_len);
event
}
pub async fn remove(self) -> Result<(), Error> {
self.receiver.remove().await
}
}
#[derive(Debug)]
pub struct PersistentWatcher {
root_len: usize,
receiver: PersistentReceiver,
}
impl PersistentWatcher {
fn new(root_len: usize, receiver: PersistentReceiver) -> Self {
PersistentWatcher { root_len, receiver }
}
pub async fn changed(&mut self) -> WatchedEvent {
let mut event = self.receiver.recv().await;
event.drain_root_len(self.root_len);
event
}
pub async fn remove(self) -> Result<(), Error> {
self.receiver.remove().await
}
}
impl WatchReceiver {
pub fn into_oneshot(self, root: &str) -> OneshotWatcher {
match self {
WatchReceiver::None => unreachable!("expect oneshot watcher, got none watcher"),
WatchReceiver::Oneshot(receiver) => OneshotWatcher::new(root.len(), receiver),
WatchReceiver::Persistent(_) => {
unreachable!("expect oneshot watcher, got persistent watcher")
},
}
}
pub fn into_persistent(self, root: &str) -> PersistentWatcher {
match self {
WatchReceiver::None => unreachable!("expect oneshot watcher, got none watcher"),
WatchReceiver::Oneshot(_) => {
unreachable!("expect oneshot watcher, got oneshot watcher")
},
WatchReceiver::Persistent(receiver) => PersistentWatcher::new(root.len(), receiver),
}
}
}