Implement matchers and actions

This commit is contained in:
Harsh Shandilya 2021-11-12 09:42:39 +05:30
parent 05201d7de7
commit 3fd078e51b
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
4 changed files with 84 additions and 2 deletions

33
Cargo.lock generated
View file

@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.45" version = "1.0.45"
@ -46,6 +55,7 @@ dependencies = [
"anyhow", "anyhow",
"clipboard", "clipboard",
"dirs", "dirs",
"regex",
"serde", "serde",
"serde_derive", "serde_derive",
"toml", "toml",
@ -115,6 +125,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@ -181,6 +197,23 @@ dependencies = [
"redox_syscall", "redox_syscall",
] ]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.130" version = "1.0.130"

View file

@ -17,6 +17,7 @@ readme = "README.md"
anyhow = "1.0.45" anyhow = "1.0.45"
clipboard = "0.5.0" clipboard = "0.5.0"
dirs = "4.0.0" dirs = "4.0.0"
regex = "1.5.4"
serde = "1.0.130" serde = "1.0.130"
serde_derive = "1.0.130" serde_derive = "1.0.130"
toml = "0.5.8" toml = "0.5.8"

View file

@ -1,4 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::str::FromStr;
use regex::Regex;
use serde_derive::Deserialize; use serde_derive::Deserialize;
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
@ -13,6 +16,14 @@ pub struct Substitutor {
pub action: Action, pub action: Action,
} }
pub trait Match {
fn check_match<'a>(self: Self, string: &'a str) -> bool;
}
pub trait Act {
fn apply_action(self: Self, input: String) -> String;
}
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub enum Matcher { pub enum Matcher {
#[serde(rename = "starts_with")] #[serde(rename = "starts_with")]
@ -25,6 +36,20 @@ pub enum Matcher {
Regex { pattern: String }, Regex { pattern: String },
} }
impl Match for Matcher {
fn check_match<'a>(self: Self, string: &'a str) -> bool {
return 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");
regex.is_match(&string)
}
};
}
}
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub enum Action { pub enum Action {
#[serde(rename = "replace")] #[serde(rename = "replace")]
@ -36,3 +61,14 @@ pub enum Action {
#[serde(rename = "remove")] #[serde(rename = "remove")]
Remove { substring: String }, Remove { substring: String },
} }
impl Act for Action {
fn apply_action(self: Self, input: String) -> String {
return match self {
Action::Replace { from, to } => input.replace(&from, &to),
Action::Prefix { prefix } => format!("{}{}", prefix, input),
Action::Suffix { suffix } => format!("{}{}", input, suffix),
Action::Remove { substring } => input.replace(&substring, ""),
};
}
}

View file

@ -1,9 +1,10 @@
mod config; mod config;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clipboard::{ClipboardContext, ClipboardProvider};
use dirs::config_dir; use dirs::config_dir;
use crate::config::Replacements; use crate::config::{Act, Match, Replacements};
fn main() -> Result<()> { fn main() -> Result<()> {
let mut config_path = config_dir().ok_or(anyhow!("Failed to get config dir"))?; let mut config_path = config_dir().ok_or(anyhow!("Failed to get config dir"))?;
@ -16,5 +17,16 @@ fn main() -> Result<()> {
} else { } else {
Replacements::default() Replacements::default()
}; };
Ok(()) let mut clipboard: ClipboardContext = ClipboardProvider::new().expect("Failed to get clipboard");
loop {
let contents = clipboard.get_contents().expect("Failed to read clipboard");
if let Some(subst) = config
.substitutors
.iter()
.find(|subst| subst.matcher.clone().check_match(&contents))
{
let result = subst.action.clone().apply_action(contents);
let _ = clipboard.set_contents(result);
};
}
} }