mecomp_tui/state/
search.rs1use tokio::sync::{
7 broadcast,
8 mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel},
9};
10
11use crate::termination::Interrupted;
12use mecomp_prost::{MusicPlayerClient, SearchRequest, SearchResult};
13
14#[derive(Debug, Clone)]
16#[allow(clippy::module_name_repetitions)]
17pub struct SearchState {
18 state_tx: UnboundedSender<SearchResult>,
19}
20
21impl SearchState {
22 #[must_use]
24 pub fn new() -> (Self, UnboundedReceiver<SearchResult>) {
25 let (state_tx, state_rx) = unbounded_channel::<SearchResult>();
26
27 (Self { state_tx }, state_rx)
28 }
29
30 pub async fn main_loop(
37 &self,
38 mut daemon: MusicPlayerClient,
39 mut action_rx: UnboundedReceiver<String>,
40 mut interrupt_rx: broadcast::Receiver<Interrupted>,
41 ) -> anyhow::Result<Interrupted> {
42 let mut state = SearchResult::default();
43
44 self.state_tx.send(state.clone())?;
46
47 let result = loop {
48 tokio::select! {
49 Some(query) = action_rx.recv() => {
52 state = daemon.search(SearchRequest::new(query, 100)).await?.into_inner();
53 self.state_tx.send(state.clone())?;
54 },
55 Ok(interrupted) = interrupt_rx.recv() => {
57 break interrupted;
58 }
59 }
60 };
61
62 Ok(result)
63 }
64}