From 13bcb918bd71de7b630a408c33e34714b216fafc Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sun, 28 Nov 2021 15:57:35 +0530 Subject: [PATCH] all: refactor to elide matchers when not required --- src/config.rs | 46 ++++++++++++++++++++++++---------------------- src/main.rs | 26 +++++++++++++++++++------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/config.rs b/src/config.rs index 50daf67..47b80f5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,39 +4,41 @@ use regex::Regex; use serde_derive::Deserialize; #[derive(Clone, Debug, Default, Deserialize)] -pub struct Replacements { - #[serde(rename = "substitutor")] - pub substitutors: Vec, +pub struct Replacements<'config> { + #[serde(rename = "substitutor", borrow, default)] + pub substitutors: Vec>, } #[derive(Clone, Debug, Deserialize)] -pub struct Substitutor { +pub struct Substitutor<'config> { #[serde(default)] - pub name: String, - pub matcher: Matcher, - pub action: Action, + pub name: &'config str, + #[serde(borrow)] + pub matcher: Matcher<'config>, + #[serde(borrow)] + pub action: Action<'config>, } #[derive(Clone, Debug, Deserialize)] -pub enum Matcher { +pub enum Matcher<'config> { #[serde(rename = "starts_with")] - StartsWith { prefix: String }, + StartsWith { prefix: &'config str }, #[serde(rename = "ends_with")] - EndsWith { suffix: String }, + EndsWith { suffix: &'config str }, #[serde(rename = "contains")] - Contains { substring: String }, + Contains { substring: &'config str }, #[serde(rename = "regex")] - Regex { pattern: String }, + Regex { pattern: &'config str }, } #[derive(Clone, Debug, Deserialize)] -pub enum Action { +pub enum Action<'config> { #[serde(rename = "replace")] - Replace { from: String, to: String }, + Replace { from: &'config str, to: &'config str }, #[serde(rename = "prefix")] - Prefix { prefix: String }, + Prefix { prefix: &'config str }, #[serde(rename = "suffix")] - Suffix { suffix: String }, + Suffix { suffix: &'config str }, } pub trait Match { @@ -44,27 +46,27 @@ pub trait Match { } pub trait Act { - fn apply_action(self, input: String) -> String; + fn apply_action(self, input: &str) -> String; } -impl Match for Matcher { +impl Match for Matcher<'_> { fn check_match(self, string: &str) -> bool { match self { Matcher::StartsWith { prefix } => string.starts_with(&prefix), Matcher::EndsWith { suffix } => string.ends_with(&suffix), Matcher::Contains { substring } => string.contains(&substring), Matcher::Regex { pattern } => { - let regex = Regex::from_str(&pattern).expect("Failed to parse regex"); + let regex = Regex::from_str(pattern).expect("Failed to parse regex"); regex.is_match(string) } } } } -impl Act for Action { - fn apply_action(self, input: String) -> String { +impl Act for Action<'_> { + fn apply_action(self, input: &str) -> String { return match self { - Action::Replace { from, to } => input.replace(&from, &to), + Action::Replace { from, to } => input.replace(from, to), Action::Prefix { prefix } => format!("{}{}", prefix, input), Action::Suffix { suffix } => format!("{}{}", input, suffix), }; diff --git a/src/main.rs b/src/main.rs index 87a7eb0..fc4a6ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod config; -use std::ops::Not; +use std::error::Error; +use std::ops::{Deref, Not}; use anyhow::{anyhow, Result}; use clipboard::{ClipboardContext, ClipboardProvider}; @@ -15,16 +16,16 @@ fn main() -> Result<()> { config_path.push("substitutor"); config_path.push("config"); config_path.set_extension("toml"); - let config: Replacements = if config_path.exists() { - let config_str = std::fs::read_to_string(config_path.as_path())?; + let config_str = std::fs::read_to_string(config_path.as_path()).unwrap_or_default(); + let config = if config_path.exists() { toml::from_str(&config_str)? } else { Replacements::default() }; let mut clipboard: ClipboardContext = ClipboardProvider::new().expect("Failed to get clipboard"); - loop { - let contents = clipboard.get_contents().expect("Failed to read clipboard"); + let mut clipboard_contents = get_clipboard_contents(&mut clipboard); + while let Ok(contents) = clipboard_contents.as_deref() { if let Some(subst) = config .substitutors .iter() @@ -33,12 +34,23 @@ fn main() -> Result<()> { if subst.name.is_empty().not() { debug!("{}: matched on {}...", &subst.name, truncate(&contents, 40)); } - let result = subst.action.clone().apply_action(contents); - if let Err(e) = clipboard.set_contents(result) { + let result = subst.action.clone().apply_action(contents.deref()); + if let Err(e) = clipboard.set_contents(result.to_owned()) { error!("{}", e); } }; + while let Ok(new_contents) = get_clipboard_contents(&mut clipboard) { + if new_contents != contents { + clipboard_contents = Ok(new_contents); + break; + }; + } } + return Ok(()); +} + +fn get_clipboard_contents(clipboard: &mut ClipboardContext) -> Result> { + clipboard.get_contents() } fn truncate(s: &str, max_chars: usize) -> &str {