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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! This crate is a rust port of the [official ProtonVPN python cli](https://github.com/ProtonVPN/linux-cli). We aim for feature parity and to track changes from the official cli. This crate's only non-rust dependency is `openvpn.` You'll need to install it using your system's package manager.
//!
//! This crate **does not** aim to have the same command line interface, or use the same config files / format.

// TODO examples

#![deny(missing_docs)]
#![deny(broken_intra_doc_links)]

use crate::{
	cli::{configure, connect, initialize, CliOptions},
	constants::APP_NAME,
	utils::project_dirs,
	vpn::util::Config,
};
use anyhow::{Context, Result};
use confy::ConfyError;
use std::io::{BufRead, Write};
use CliOptions::*;

/// This module contains all the structs for storing args passed in from the command line.
///
/// `cli`'s submodules each correspond to one of the cli subcommands. Each submodule contains a function which wraps all the others in its module. This module reexports that function for use in the cli.
pub mod cli;

/// Assorted constants for use throughout the crate. Mostly strings and a map for looking up countries.
pub mod constants;
/// Miscellaneous functions. See the documentation for this module's members instead
pub(crate) mod utils;
/// Functions for interacting with the `openvpn` binary, including starting / stopping a connection, and creating config files. 
pub mod vpn;

/// The main function in src.rs is a wrapper of this function.
pub fn main<R, W>(
	opt: CliOptions,
	config_res: Result<Config, ConfyError>,
	mut r: &mut R,
	mut w: &mut W,
) -> Result<()>
where
	R: BufRead,
	W: Write,
{
	let pdir = project_dirs();

	if let Ok(mut config) = config_res {
		match opt {
			Init => {
				initialize(&mut config.user, &pdir, &mut r, &mut w)?;
				confy::store(APP_NAME, config.user).context("Couldn't store your configuration")?;
			}
			Connect(flags) => {
				let _connection = connect(&flags, &mut config, &pdir)?;
			}
			Reconnect => {}
			Disconnect => {}
			Status => {}
			Configure => {
				configure(&mut config.user, &mut r, &mut w)?;
				confy::store(APP_NAME, config.user).context("Couldn't store your configuration")?;
			}
			Refresh => {}
			Examples => {}
		};
	} else {
		if let Init = opt {
			initialize(&mut Default::default(), &pdir, &mut r, &mut w)?;
		} else {
			writeln!(
				&mut w,
				"Unable to load your profile. Try running `protonvpn init` again."
			)?;
		}
	}
	Ok(())
}