use anyhow::{Context, Result}; use mullvad_management_interface::MullvadProxyClient; use std::{ fs::File, io::{BufReader, read_to_string, stdin}, }; /// Read a settings patch and send it to the daemon for validation and /// application. /// /// * If `source` is "-", read the patch from standard input /// * Otherwise, interpret `source` as a filepath and read from the provided file pub async fn import(source: String) -> Result<()> { let json_blob = tokio::task::spawn_blocking(move || match source.as_str() { "-" => read_to_string(BufReader::new(stdin())).context("Failed to read from stdin"), _ => read_to_string(File::open(&source)?) .context(format!("Failed to read from path: {source}")), }) .await .unwrap()?; let mut rpc = MullvadProxyClient::new().await?; rpc.apply_json_settings(json_blob) .await .context("Error applying patch")?; println!("Settings applied"); Ok(()) } /// Output a settings patch including all currently patchable settings. /// /// * If `source` is "-", write the patch to standard output /// * Otherwise, interpret `source` as a filepath and write to the provided file pub async fn export(dest: String) -> Result<()> { let mut rpc = MullvadProxyClient::new().await?; let blob = rpc .export_json_settings() .await .context("Error exporting patch")?; match dest.as_str() { "-" => { println!("{blob}"); Ok(()) } _ => tokio::fs::write(&dest, blob) .await .context(format!("Failed to write to path {dest}")), } }