From 87fabdfae282361d0b3d1c733779fa673d5db572 Mon Sep 17 00:00:00 2001 From: shouya <526598+shouya@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:09:00 +0900 Subject: [PATCH 1/3] case_sensitive option for highlight filter --- src/filter/highlight.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/filter/highlight.rs b/src/filter/highlight.rs index fc93d9d..e0d59be 100644 --- a/src/filter/highlight.rs +++ b/src/filter/highlight.rs @@ -19,7 +19,10 @@ pub struct HighlightConfig { #[serde(flatten)] keywords: KeywordsOrPatterns, /// Background color to use for highlighting. Default is yellow. + #[serde(default)] bg_color: Option, + #[serde(default)] + case_sensitive: Option, } #[derive( @@ -55,7 +58,8 @@ impl FeedFilterConfig for HighlightConfig { async fn build(self) -> Result { let patterns = self.keywords.into_patterns()?; let bg_color = self.bg_color.unwrap_or_else(|| "#ffff00".into()); - Highlight::new(&patterns, bg_color) + let case_sensitive = self.case_sensitive.unwrap_or(false); + Highlight::new(&patterns, bg_color, case_sensitive) } } @@ -104,13 +108,18 @@ impl Highlight { fn new>( patterns: &[T], bg_color: String, + case_sensitive: bool, ) -> Result { let regexset = RegexSetBuilder::new(patterns) - .case_insensitive(true) + .case_insensitive(case_sensitive) .build()?; let patterns = patterns .iter() - .map(|p| RegexBuilder::new(p.as_ref()).case_insensitive(true).build()) + .map(|p| { + RegexBuilder::new(p.as_ref()) + .case_insensitive(case_sensitive) + .build() + }) .collect::, _>>()?; Ok(Self { From f1ef5c2a4625bbc3480e637bdcda18aa5424f3e6 Mon Sep 17 00:00:00 2001 From: shouya <526598+shouya@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:19:48 +0900 Subject: [PATCH 2/3] fix tests --- src/filter/highlight.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/filter/highlight.rs b/src/filter/highlight.rs index e0d59be..07d84e1 100644 --- a/src/filter/highlight.rs +++ b/src/filter/highlight.rs @@ -111,13 +111,13 @@ impl Highlight { case_sensitive: bool, ) -> Result { let regexset = RegexSetBuilder::new(patterns) - .case_insensitive(case_sensitive) + .case_insensitive(!case_sensitive) .build()?; let patterns = patterns .iter() .map(|p| { RegexBuilder::new(p.as_ref()) - .case_insensitive(case_sensitive) + .case_insensitive(!case_sensitive) .build() }) .collect::, _>>()?; @@ -250,7 +250,7 @@ mod test { #[test] fn test_highlighting() { let keywords = vec!["foo", "bar"]; - let highlight = Highlight::new(&keywords, "#ffff00".into()) + let highlight = Highlight::new(&keywords, "#ffff00".into(), false) .expect("failed to build highlighter"); let html = r#"

FOO

foo
bar

@@ -283,6 +283,7 @@ highlight: keywords: vec!["foo".into(), "bar".into()], }, bg_color: Some("#ffff00".into()), + case_sensitive: None, }, ); @@ -298,6 +299,7 @@ highlight: patterns: vec![r"\bfoo\b".into()], }, bg_color: Some("#ffff00".into()), + case_sensitive: None, }, ); } From e4a6094976fa18a3710dfd25cb787200b8832fce Mon Sep 17 00:00:00 2001 From: shouya <526598+shouya@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:21:09 +0900 Subject: [PATCH 3/3] add case_sensitive option to `sanitize` filter --- src/filter/sanitize.rs | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/filter/sanitize.rs b/src/filter/sanitize.rs index 41165a0..6f46c65 100644 --- a/src/filter/sanitize.rs +++ b/src/filter/sanitize.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use regex::Regex; +use regex::{Regex, RegexBuilder}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -12,9 +12,11 @@ use super::{FeedFilter, FeedFilterConfig, FilterContext}; #[derive( JsonSchema, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, )] -struct SanitizeOpReplaceConfig { +struct ReplaceConfig { from: String, to: String, + #[serde(default)] + case_sensitive: Option, } #[derive( @@ -26,9 +28,9 @@ pub struct SanitizeOpConfig { /// Remove all matches of the regex remove_regex: Option, /// Replace all occurrences of the string - replace: Option, + replace: Option, /// Replace all matches of the regex - replace_regex: Option, + replace_regex: Option, } impl SanitizeOpConfig { @@ -48,7 +50,16 @@ impl SanitizeOpConfig { macro_rules! parse_regex { ($regex:expr) => { - Regex::new(&$regex).map_err(ConfigError::from)? + RegexBuilder::new(&$regex) + .case_insensitive(true) + .build() + .map_err(ConfigError::from)? + }; + ($regex:expr, $cs:expr) => { + RegexBuilder::new(&$regex) + .case_insensitive($cs.unwrap_or(true)) + .build() + .map_err(ConfigError::from)? }; } @@ -62,13 +73,15 @@ impl SanitizeOpConfig { } if let Some(text) = self.replace { - let from = parse_regex!(regex::escape(&text.from)); + let case_sensitive = text.case_sensitive; + let from = parse_regex!(regex::escape(&text.from), case_sensitive); let to = text.to; return Ok(SanitizeOp::Replace(from, to)); } if let Some(repl) = self.replace_regex { - let from = parse_regex!(repl.from); + let case_sensitive = repl.case_sensitive; + let from = parse_regex!(repl.from, case_sensitive); let to = repl.to; return Ok(SanitizeOp::Replace(from, to)); } @@ -182,9 +195,10 @@ mod test { SanitizeOpConfig { remove: None, remove_regex: None, - replace: Some(SanitizeOpReplaceConfig { + replace: Some(ReplaceConfig { from: "bar".into(), to: "baz".into(), + case_sensitive: None, }), replace_regex: None, }, @@ -192,9 +206,10 @@ mod test { remove: None, remove_regex: None, replace: None, - replace_regex: Some(SanitizeOpReplaceConfig { + replace_regex: Some(ReplaceConfig { from: r"\w+".into(), to: "qux".into(), + case_sensitive: None, }), }, ],