summaryrefslogtreecommitdiffhomepage
path: root/mullvad-cli/src/cmds/disconnect.rs
blob: 96d5843d205ecb99c453db4d57993bfffe38cee0 (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
42
43
44
45
46
47
48
49
use crate::{format, new_rpc_client, state, Command, Error, Result};
use futures::StreamExt;
use mullvad_management_interface::types::tunnel_state::State::Disconnected;

pub struct Disconnect;

#[mullvad_management_interface::async_trait]
impl Command for Disconnect {
    fn name(&self) -> &'static str {
        "disconnect"
    }

    fn clap_subcommand(&self) -> clap::App<'static, 'static> {
        clap::SubCommand::with_name(self.name())
            .about("Command the client to disconnect the VPN tunnel")
            .arg(
                clap::Arg::with_name("wait")
                    .long("wait")
                    .short("w")
                    .help("Wait until disconnected before exiting"),
            )
    }

    async fn run(&self, matches: &clap::ArgMatches<'_>) -> Result<()> {
        let mut rpc = new_rpc_client().await?;

        let receiver_option = if matches.is_present("wait") {
            Some(state::state_listen(rpc.clone()))
        } else {
            None
        };

        if rpc.disconnect_tunnel(()).await?.into_inner() {
            if let Some(mut receiver) = receiver_option {
                while let Some(state) = receiver.next().await {
                    let state = state?;
                    format::print_state(&state);
                    match state.state.unwrap() {
                        Disconnected(_) => return Ok(()),
                        _ => {}
                    }
                }
                return Err(Error::StatusListenerFailed);
            }
        }

        Ok(())
    }
}