summaryrefslogtreecommitdiffhomepage
path: root/mullvad-cli/src/state.rs
blob: 4cf826214fa2b6a9909c02b4d6633b93bdb0632b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use crate::{Error, Result};
use futures::{
    channel::{mpsc, mpsc::Receiver},
    SinkExt,
};
use mullvad_management_interface::{
    types::{daemon_event::Event as EventType, TunnelState},
    ManagementServiceClient,
};

// Spawns a new task that listens for tunnel state changes and forwards it through the returned
// channel. Panics if called from outside of the Tokio runtime.
pub fn state_listen(mut rpc: ManagementServiceClient) -> Receiver<Result<TunnelState>> {
    let (mut sender, receiver) = mpsc::channel::<Result<TunnelState>>(1);
    tokio::spawn(async move {
        match rpc.events_listen(()).await {
            Ok(events) => {
                let mut events = events.into_inner();
                loop {
                    let forward = match events.message().await {
                        Ok(Some(event)) => match event.event.unwrap() {
                            EventType::TunnelState(new_state) => Ok(new_state),
                            _ => continue,
                        },
                        Ok(None) => break,
                        Err(status) => Err(Error::RpcFailed(status)),
                    };

                    if let Err(_) = sender.send(forward).await {
                        break;
                    }
                }
            }
            Err(status) => {
                let _ = sender.send(Err(Error::RpcFailed(status))).await;
            }
        }
    });

    receiver
}