use tokio::sync::{
broadcast,
mpsc::{self, UnboundedReceiver, UnboundedSender},
};
use crate::termination::{Interrupted, Terminator};
use super::{Action, State};
pub struct StateStore {
state_tx: UnboundedSender<State>,
}
impl StateStore {
pub fn new() -> (Self, UnboundedReceiver<State>) {
let (state_tx, state_rx) = mpsc::unbounded_channel::<State>();
(StateStore { state_tx }, state_rx)
}
}
impl StateStore {
pub async fn main_loop(
self,
mut terminator: Terminator,
mut action_rx: UnboundedReceiver<Action>,
mut interrupt_rx: broadcast::Receiver<Interrupted>,
) -> anyhow::Result<Interrupted> {
let mut state = State::default();
self.state_tx.send(state.clone())?;
let result = loop {
tokio::select! {
Some(action) = action_rx.recv() => match action {
Action::IncCounter => {
state.upcount();
},
Action::DecCounter => {
state.downcount();
},
Action::Exit => {
let _ = terminator.terminate(Interrupted::UserInt);
break Interrupted::UserInt;
}
},
Ok(interrupted) = interrupt_rx.recv() => {
break interrupted;
}
}
};
Ok(result)
}
}