diff --git a/Cargo.lock b/Cargo.lock index 75ab64a..24a8738 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -375,6 +375,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -399,6 +408,29 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoize" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2ae6b7c9fbefd9bad492a5c65013e9fd10d6db3f971ee1e2d1c55485dd5135" +dependencies = [ + "lazy_static", + "lru", + "memoize-inner", +] + +[[package]] +name = "memoize-inner" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bfde264c318ec8c2de5c39e0ba3910fac8d1065e3b947b183ebd884b799719b" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "miette" version = "5.7.0" @@ -843,6 +875,7 @@ version = "0.1.1" dependencies = [ "cli-clipboard", "knuffel", + "memoize", "miette", "url", "wildmatch", diff --git a/Cargo.toml b/Cargo.toml index 7b1a3a0..bb40e4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ license = "NVPLv7+" [dependencies] cli-clipboard = "0.4.0" knuffel = "3.0.0" +memoize = { version = "0.4.0", features = ["full"] } miette = { version = "5.7.0", features = ["fancy"] } url = "2.3.1" wildmatch = "2.1.1" diff --git a/src/main.rs b/src/main.rs index 28976df..0283438 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use cli_clipboard::{ClipboardContext, ClipboardProvider}; +use memoize::memoize; use miette::{miette, IntoDiagnostic, Result}; use std::{env, fs}; use url::Url; @@ -46,7 +47,7 @@ fn main() -> Result<()> { // Clipboard changed if contents != last_contents { last_contents = contents.clone(); - if let Ok(url) = clean_url(contents, &patterns) { + if let Ok(url) = clean_url(contents, patterns.clone()) { // Update clipboard clipboard.set_contents(url.clone()).map_err(|e| { miette!(format!("Couldn't set clipboard contents: {e}")) @@ -61,14 +62,15 @@ fn main() -> Result<()> { } } -fn clean_url(text: String, patterns: &Vec) -> Result { +#[memoize(Capacity: 1024)] +fn clean_url(text: String, patterns: Vec) -> Result { if let Ok(mut url) = Url::parse(&text) { let url_inner = url.clone(); // Skip URLs without a host - let Some(host) = url_inner.host_str() else { return Err(miette!("URL {} does not have a host", url_inner)) }; + let Some(host) = url_inner.host_str() else { return Err(format!("URL {} does not have a host", url_inner)) }; - for pattern in patterns { + for pattern in &patterns { let url_inner = url.clone(); match pattern.split_once('@') { Some((param, domain)) => { @@ -97,6 +99,6 @@ fn clean_url(text: String, patterns: &Vec) -> Result { Ok(url) } else { - Err(miette!("Contents are not a valid URL")) + Err(format!("Contents are not a valid URL")) } }