diff --git a/Cargo.lock b/Cargo.lock index 197a5ad..b5fcf02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1872,6 +1872,7 @@ dependencies = [ "tokio", "tokio-util", "toml", + "toml_edit", "webrtc-dtls", "webrtc-util", ] diff --git a/Cargo.toml b/Cargo.toml index 5425e16..29c0097 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ shadow-rs = { version = "1.2.0", features = ["metadata"] } hickory-resolver = "0.25.2" toml = "0.8" +toml_edit = { version = "0.22", features = ["serde"] } serde = { version = "1.0", features = ["derive"] } log = "0.4.20" env_logger = "0.11.3" diff --git a/lan-mouse-cli/src/lib.rs b/lan-mouse-cli/src/lib.rs index 26e7a05..884e928 100644 --- a/lan-mouse-cli/src/lib.rs +++ b/lan-mouse-cli/src/lib.rs @@ -71,6 +71,8 @@ enum CliSubcommand { }, /// deauthorize a public key RemoveAuthorizedKey { sha256_fingerprint: String }, + /// save configuration to file + SaveConfig, } pub async fn run(args: CliArgs) -> Result<(), CliError> { @@ -162,6 +164,7 @@ async fn execute(cmd: CliSubcommand) -> Result<(), CliError> { tx.request(FrontendRequest::RemoveAuthorizedKey(sha256_fingerprint)) .await? } + CliSubcommand::SaveConfig => tx.request(FrontendRequest::SaveConfiguration).await?, } Ok(()) } diff --git a/src/config.rs b/src/config.rs index caad4d7..767e79e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,6 +11,7 @@ use std::path::{Path, PathBuf}; use std::{collections::HashSet, io}; use thiserror::Error; use toml; +use toml_edit::{self, DocumentMut}; use lan_mouse_cli::CliArgs; use lan_mouse_ipc::{DEFAULT_PORT, Position}; @@ -44,7 +45,7 @@ fn default_path() -> Result { Ok(PathBuf::from(default_path)) } -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, Debug, Default)] struct ConfigToml { capture_backend: Option, emulation_backend: Option, @@ -414,15 +415,21 @@ impl Config { /// set configured clients pub fn set_clients(&mut self, clients: Vec) { + if clients.is_empty() { + return; + } if self.config_toml.is_none() { self.config_toml = Default::default(); } self.config_toml.as_mut().expect("config").clients = - clients.into_iter().map(|c| c.into()).collect::>(); + Some(clients.into_iter().map(|c| c.into()).collect::>()); } /// set authorized keys pub fn set_authorized_keys(&mut self, fingerprints: HashMap) { + if fingerprints.is_empty() { + return; + } if self.config_toml.is_none() { self.config_toml = Default::default(); } @@ -432,7 +439,24 @@ impl Config { .authorized_fingerprints = Some(fingerprints); } - pub fn write_back(&self) { - todo!() + pub fn write_back(&self) -> Result<(), io::Error> { + log::info!("writing config to {:?}", &self.config_path); + /* load the current configuration file */ + let current_config = fs::read_to_string(&self.config_path)?; + let current_config = current_config.parse::().expect("fix me"); + let _current_config = + toml_edit::de::from_document::(current_config).expect("fixme"); + + /* the new config */ + let new_config = self.config_toml.clone().unwrap_or_default(); + // let new_config = toml_edit::ser::to_document::(&new_config).expect("fixme"); + let new_config = toml_edit::ser::to_string_pretty(&new_config).expect("todo"); + + /* TODO merge documents */ + + /* write new config to file */ + fs::write(&self.config_path, new_config)?; + + Ok(()) } } diff --git a/src/service.rs b/src/service.rs index ad83616..8d81e29 100644 --- a/src/service.rs +++ b/src/service.rs @@ -223,7 +223,9 @@ impl Service { self.config.set_clients(clients); let authorized_keys = self.authorized_keys.read().expect("lock").clone(); self.config.set_authorized_keys(authorized_keys); - self.config.write_back(); + if let Err(e) = self.config.write_back() { + log::warn!("failed to write config: {e}"); + } } async fn handle_frontend_pending(&mut self) {