mecomp_tui/state/
search.rs1use std::sync::Arc;
7
8use tokio::sync::{
9 broadcast,
10 mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel},
11};
12
13use mecomp_core::rpc::{MusicPlayerClient, SearchResult};
14
15use crate::termination::Interrupted;
16
17#[derive(Debug, Clone)]
19#[allow(clippy::module_name_repetitions)]
20pub struct SearchState {
21 state_tx: UnboundedSender<SearchResult>,
22}
23
24impl SearchState {
25 #[must_use]
27 pub fn new() -> (Self, UnboundedReceiver<SearchResult>) {
28 let (state_tx, state_rx) = unbounded_channel::<SearchResult>();
29
30 (Self { state_tx }, state_rx)
31 }
32
33 pub async fn main_loop(
40 &self,
41 daemon: Arc<MusicPlayerClient>,
42 mut action_rx: UnboundedReceiver<String>,
43 mut interrupt_rx: broadcast::Receiver<Interrupted>,
44 ) -> anyhow::Result<Interrupted> {
45 let mut state = SearchResult::default();
46
47 self.state_tx.send(state.clone())?;
49
50 let result = loop {
51 tokio::select! {
52 Some(query) = action_rx.recv() => {
55 let ctx = tarpc::context::current();
56 state = daemon.search(ctx, query, 100).await?;
57 self.state_tx.send(state.clone())?;
58 },
59 Ok(interrupted) = interrupt_rx.recv() => {
61 break interrupted;
62 }
63 }
64 };
65
66 Ok(result)
67 }
68}