From c5394d21bcbffadf35178b1f8e01921298467d3b Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 23 Dec 2024 14:45:20 +0800 Subject: [PATCH] Improve Toggle code by use Arc for avoid clone rules. --- autocorrect/src/code/code.rs | 10 +- autocorrect/src/code/markdown.rs | 2 - autocorrect/src/config/toggle.rs | 195 +++++++++++++++++-------------- autocorrect/src/lib.rs | 2 +- autocorrect/src/result/mod.rs | 37 +++--- 5 files changed, 127 insertions(+), 119 deletions(-) diff --git a/autocorrect/src/code/code.rs b/autocorrect/src/code/code.rs index ca292c55..d2528eae 100644 --- a/autocorrect/src/code/code.rs +++ b/autocorrect/src/code/code.rs @@ -62,10 +62,8 @@ fn format_pair(results: &mut O, pair: Pair) { // If they has CJK chars, disable `halfwidth-punctuation` rule temporary. let mut last_toggle = None; if rule_name == "block" && CJK_RE.is_match(pair_str) { - last_toggle = Some(results.get_toggle()); - results.toggle_merge(toggle::Toggle::Disable(vec![ - "halfwidth-punctuation".to_owned() - ])); + last_toggle = Some(results.get_toggle().clone()); + results.toggle_merge_for_codeblock(); } for child in sub_pairs { @@ -74,7 +72,7 @@ fn format_pair(results: &mut O, pair: Pair) { } // Restore toggle if last_toggle is some - if let Some(t) = last_toggle { + if let Some(t) = &last_toggle { results.toggle(t); } @@ -93,7 +91,7 @@ pub fn format_or_lint(results: &mut O, rule_name: &str, // Check AutoCorrect enable/disable toggle marker // If disable results.is_enabled() will be false if rule_name == "comment" || rule_name == "COMMENT" { - results.toggle(toggle::parse(part)); + results.toggle(&toggle::parse(part)); } let disabled_rules = results.get_toggle().disable_rules(); diff --git a/autocorrect/src/code/markdown.rs b/autocorrect/src/code/markdown.rs index 391f5c6e..435d55d9 100644 --- a/autocorrect/src/code/markdown.rs +++ b/autocorrect/src/code/markdown.rs @@ -361,8 +361,6 @@ mod tests { #[test] fn test_disable_context_codeblock() { - use std::collections::HashMap; - let last_mode = *crate::config::Config::current() .context .get("codeblock") diff --git a/autocorrect/src/config/toggle.rs b/autocorrect/src/config/toggle.rs index 1aab08a3..997168e1 100644 --- a/autocorrect/src/config/toggle.rs +++ b/autocorrect/src/config/toggle.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; use pest::Parser; use pest_derive::Parser; @@ -11,18 +11,45 @@ pub struct ToggleParser; pub enum Toggle { None, // Empty to disable all - Disable(Vec), + Disable(Arc>), // Empty to enable all - Enable(Vec), + Enable(Arc>), } impl Default for Toggle { fn default() -> Self { - Toggle::Enable(vec![]) + Toggle::enable(vec![]) } } impl Toggle { + pub fn none() -> Self { + Toggle::None + } + + pub fn enable(rules: Vec<&str>) -> Self { + let rules = rules + .into_iter() + .map(|r| (r.to_lowercase().to_string(), true)) + .collect(); + Toggle::Enable(Arc::new(rules)) + } + + pub fn disable(rules: Vec<&str>) -> Self { + let rules = rules + .into_iter() + .map(|r| (r.to_lowercase().to_string(), true)) + .collect(); + Toggle::Disable(Arc::new(rules)) + } + + pub fn is_none(&self) -> bool { + match self { + Toggle::None => true, + _ => false, + } + } + pub fn match_rule(&self, rule_name: &str) -> Option { match self { Toggle::None => None, @@ -30,29 +57,23 @@ impl Toggle { if rules.is_empty() { Some(false) } else { - Some(!rules.contains(&rule_name.to_string())) + Some(!rules.contains_key(rule_name)) } } Toggle::Enable(rules) => { if rules.is_empty() { Some(true) } else { - Some(rules.contains(&rule_name.to_string())) + Some(rules.contains_key(rule_name)) } } } } - pub fn disable_rules(&self) -> HashMap { + pub fn disable_rules(&self) -> Arc> { match self { - Toggle::Disable(rules) => { - let mut map = HashMap::new(); - for rule in rules { - map.insert(rule.to_string(), true); - } - map - } - _ => HashMap::new(), + Toggle::Disable(rules) => rules.clone(), + _ => Arc::new(HashMap::new()), } } @@ -61,26 +82,41 @@ impl Toggle { match new_toggle { Toggle::Disable(rules) => { if let Toggle::Disable(old_rules) = self { + let mut old_rules = old_rules + .iter() + .map(|(k, v)| (k.clone(), *v)) + .collect::>(); if !old_rules.is_empty() { - old_rules.extend(rules.clone()); + for (k, v) in rules.iter() { + old_rules.insert(k.clone(), *v); + } } if rules.is_empty() { old_rules.clear(); } + *self = Toggle::Disable(Arc::new(old_rules)); } else { *self = Toggle::Disable(rules); } } Toggle::Enable(rules) => { if let Toggle::Enable(old_rules) = self { + let mut old_rules = old_rules + .iter() + .map(|(k, v)| (k.clone(), *v)) + .collect::>(); + if !old_rules.is_empty() { - old_rules.extend(rules.clone()); + for (k, v) in rules.iter() { + old_rules.insert(k.clone(), *v); + } } if rules.is_empty() { old_rules.clear(); } + *self = Toggle::Enable(Arc::new(old_rules)); } else { *self = Toggle::Enable(rules); } @@ -98,20 +134,20 @@ pub fn parse(input: &str) -> Toggle { let mut rules = vec![]; for pair in pair.into_inner() { if pair.as_rule() == Rule::rule_name { - rules.push(pair.as_str().to_lowercase().to_owned()); + rules.push(pair.as_str()); } } - return Toggle::Disable(rules); + return Toggle::disable(rules); } Rule::enable => { let mut rules = vec![]; for pair in pair.into_inner() { if pair.as_rule() == Rule::rule_name { - rules.push(pair.as_str().to_lowercase().to_owned()); + rules.push(pair.as_str()); } } - return Toggle::Enable(rules); + return Toggle::enable(rules); } _ => {} } @@ -128,80 +164,67 @@ mod tests { #[test] fn it_match_rule() { - assert_eq!(Toggle::Enable(vec![]).match_rule("rule"), Some(true)); - assert_eq!(Toggle::Enable(vec![]).match_rule("foo"), Some(true)); - assert_eq!(Toggle::Enable(vec![]).match_rule(""), Some(true)); + assert_eq!(Toggle::enable(vec![]).match_rule("rule"), Some(true)); + assert_eq!(Toggle::enable(vec![]).match_rule("foo"), Some(true)); + assert_eq!(Toggle::enable(vec![]).match_rule(""), Some(true)); + assert_eq!(Toggle::enable(vec!["foo"]).match_rule("foo"), Some(true)); + assert_eq!(Toggle::enable(vec!["bar"]).match_rule("foo"), Some(false)); assert_eq!( - Toggle::Enable(vec!["foo".to_owned()]).match_rule("foo"), - Some(true) - ); - assert_eq!( - Toggle::Enable(vec!["bar".to_owned()]).match_rule("foo"), - Some(false) - ); - assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]).match_rule("foo"), + Toggle::enable(vec!["foo", "bar"]).match_rule("foo"), Some(true) ); assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]).match_rule("bar"), + Toggle::enable(vec!["foo", "bar"]).match_rule("bar"), Some(true) ); assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]).match_rule("dar"), + Toggle::enable(vec!["foo", "bar"]).match_rule("dar"), Some(false) ); assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]).match_rule(""), + Toggle::enable(vec!["foo", "bar"]).match_rule(""), Some(false) ); } #[test] fn it_parse() { - assert_eq!(Toggle::Enable(vec![]), parse("autocorrect-enable")); - assert_eq!(Toggle::Enable(vec![]), parse("// autocorrect-enable")); - assert_eq!(Toggle::Enable(vec![]), parse("# autocorrect-enable")); - assert_eq!(Toggle::Enable(vec![]), parse("# autocorrect: true")); - assert_eq!(Toggle::Enable(vec![]), parse("# autocorrect:true")); - assert_eq!(Toggle::Disable(vec![]), parse("# autocorrect: false")); - assert_eq!(Toggle::Disable(vec![]), parse("# autocorrect:false")); - assert_eq!(Toggle::Disable(vec![]), parse("# autocorrect-disable")); - assert_eq!(Toggle::Disable(vec![]), parse("// autocorrect-disable")); - assert_eq!(Toggle::None, parse("// hello world")); + assert_eq!(Toggle::enable(vec![]), parse("autocorrect-enable")); + assert_eq!(Toggle::enable(vec![]), parse("// autocorrect-enable")); + assert_eq!(Toggle::enable(vec![]), parse("# autocorrect-enable")); + assert_eq!(Toggle::enable(vec![]), parse("# autocorrect: true")); + assert_eq!(Toggle::enable(vec![]), parse("# autocorrect:true")); + assert_eq!(Toggle::disable(vec![]), parse("# autocorrect: false")); + assert_eq!(Toggle::disable(vec![]), parse("# autocorrect:false")); + assert_eq!(Toggle::disable(vec![]), parse("# autocorrect-disable")); + assert_eq!(Toggle::disable(vec![]), parse("// autocorrect-disable")); + assert_eq!(Toggle::none(), parse("// hello world")); } #[test] fn it_parse_with_rules() { - assert_eq!( - Toggle::Enable(vec!["foo".to_owned()]), - parse("autocorrect-enable foo") - ); + assert_eq!(Toggle::enable(vec!["foo"]), parse("autocorrect-enable foo")); assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]), + Toggle::enable(vec!["foo", "bar"]), parse("// autocorrect-enable foo, bar") ); assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]), + Toggle::enable(vec!["foo", "bar"]), parse("// autocorrect-enable foo,bar") ); assert_eq!( - Toggle::Disable(vec!["foo".to_owned()]), + Toggle::disable(vec!["foo"]), parse("# autocorrect-disable foo") ); assert_eq!( - Toggle::Disable(vec!["foo".to_owned(), "bar".to_owned()]), + Toggle::disable(vec!["foo", "bar"]), parse("// autocorrect-disable foo,bar") ); assert_eq!( - Toggle::Disable(vec![ - "foo".to_owned(), - "bar".to_owned(), - "foo-bar_dar".to_owned() - ]), + Toggle::disable(vec!["foo", "bar", "foo-bar_dar"]), parse("// autocorrect-disable foo,Bar, Foo-bAr_dar") ); } @@ -237,39 +260,33 @@ mod tests { #[test] fn test_merge() { - let mut toggle = Toggle::Enable(vec!["foo".to_owned()]); - toggle.merge(Toggle::Enable(vec!["bar".to_owned()])); - assert_eq!( - Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]), - toggle - ); - toggle.merge(Toggle::Enable(vec![])); - assert_eq!(Toggle::Enable(vec![]), toggle); - toggle.merge(Toggle::Enable(vec!["foo".to_owned()])); - assert_eq!(Toggle::Enable(vec![]), toggle); + let mut toggle = Toggle::enable(vec!["foo"]); + toggle.merge(Toggle::enable(vec!["bar"])); + assert_eq!(Toggle::enable(vec!["foo", "bar"]), toggle); + toggle.merge(Toggle::enable(vec![])); + assert_eq!(Toggle::enable(vec![]), toggle); + toggle.merge(Toggle::enable(vec!["foo"])); + assert_eq!(Toggle::enable(vec![]), toggle); - let mut toggle = Toggle::Disable(vec!["foo".to_owned(), "bar".to_owned()]); - toggle.merge(Toggle::Disable(vec!["dar".to_owned()])); - assert_eq!( - Toggle::Disable(vec!["foo".to_owned(), "bar".to_owned(), "dar".to_owned()]), - toggle - ); - toggle.merge(Toggle::Disable(vec![])); - assert_eq!(Toggle::Disable(vec![]), toggle); - toggle.merge(Toggle::Disable(vec!["foo".to_owned()])); - assert_eq!(Toggle::Disable(vec![]), toggle); + let mut toggle = Toggle::disable(vec!["foo", "bar"]); + toggle.merge(Toggle::disable(vec!["dar"])); + assert_eq!(Toggle::disable(vec!["foo", "bar", "dar"]), toggle); + toggle.merge(Toggle::disable(vec![])); + assert_eq!(Toggle::disable(vec![]), toggle); + toggle.merge(Toggle::disable(vec!["foo"])); + assert_eq!(Toggle::disable(vec![]), toggle); // Merge with disable enum value, override - let mut toggle = Toggle::Enable(vec!["foo".to_owned(), "bar".to_owned()]); - toggle.merge(Toggle::Disable(vec!["dar".to_owned()])); - assert_eq!(Toggle::Disable(vec!["dar".to_owned()]), toggle); - toggle.merge(Toggle::None); - assert_eq!(Toggle::None, toggle); + let mut toggle = Toggle::enable(vec!["foo", "bar"]); + toggle.merge(Toggle::disable(vec!["dar"])); + assert_eq!(Toggle::disable(vec!["dar"]), toggle); + toggle.merge(Toggle::none()); + assert_eq!(Toggle::none(), toggle); - let mut toggle = Toggle::Disable(vec!["foo".to_owned(), "bar".to_owned()]); - toggle.merge(Toggle::Enable(vec!["dar".to_owned()])); - assert_eq!(Toggle::Enable(vec!["dar".to_owned()]), toggle); - toggle.merge(Toggle::None); - assert_eq!(Toggle::None, toggle); + let mut toggle = Toggle::disable(vec!["foo", "bar"]); + toggle.merge(Toggle::enable(vec!["dar"])); + assert_eq!(Toggle::enable(vec!["dar"]), toggle); + toggle.merge(Toggle::none()); + assert_eq!(Toggle::none(), toggle); } } diff --git a/autocorrect/src/lib.rs b/autocorrect/src/lib.rs index 919e2bce..bcf274e5 100644 --- a/autocorrect/src/lib.rs +++ b/autocorrect/src/lib.rs @@ -92,7 +92,7 @@ macro_rules! regexp { #[allow(unused)] macro_rules! map { {$($key:expr => $value:expr),+ $(,)?} => {{ - let mut m = HashMap::new(); + let mut m = std::collections::HashMap::new(); $( m.insert($key, $value); )+ diff --git a/autocorrect/src/result/mod.rs b/autocorrect/src/result/mod.rs index aa545aaa..a9b68d6c 100644 --- a/autocorrect/src/result/mod.rs +++ b/autocorrect/src/result/mod.rs @@ -46,30 +46,25 @@ pub trait Results { #[allow(unused)] fn to_string(&self) -> String; fn is_lint(&self) -> bool; - fn get_toggle(&self) -> toggle::Toggle; - fn set_toggle(&mut self, t: toggle::Toggle); + fn get_toggle(&self) -> &toggle::Toggle; + fn toggle_mut(&mut self) -> &mut toggle::Toggle; /// Move and save current line,col return the previus line number fn move_cursor(&mut self, part: &str) -> (usize, usize); /// Toggle AutoCorrrect template enable or disable /// If new toggle is None, ignore - fn toggle(&mut self, new_toggle: toggle::Toggle) { - if new_toggle == toggle::Toggle::None { + fn toggle(&mut self, new_toggle: &toggle::Toggle) { + if new_toggle.is_none() { return; } - self.set_toggle(new_toggle); + *self.toggle_mut() = new_toggle.clone(); } - fn toggle_merge(&mut self, new_toggle: toggle::Toggle) { - if new_toggle == toggle::Toggle::None { - return; - } - - let mut toggle = self.get_toggle(); - toggle.merge(new_toggle); - self.set_toggle(toggle); + fn toggle_merge_for_codeblock(&mut self) { + self.toggle_mut() + .merge(toggle::Toggle::disable(vec!["halfwidth-punctuation"])); } /// Is AutoCorrrect current is enable @@ -153,12 +148,12 @@ impl Results for FormatResult { false } - fn set_toggle(&mut self, t: toggle::Toggle) { - self.toggle = t + fn toggle_mut(&mut self) -> &mut toggle::Toggle { + &mut self.toggle } - fn get_toggle(&self) -> toggle::Toggle { - self.toggle.clone() + fn get_toggle(&self) -> &toggle::Toggle { + &self.toggle } fn move_cursor(&mut self, _part: &str) -> (usize, usize) { @@ -252,12 +247,12 @@ impl Results for LintResult { true } - fn set_toggle(&mut self, t: toggle::Toggle) { - self.toggle = t + fn get_toggle(&self) -> &toggle::Toggle { + &self.toggle } - fn get_toggle(&self) -> toggle::Toggle { - self.toggle.clone() + fn toggle_mut(&mut self) -> &mut toggle::Toggle { + &mut self.toggle } /// Move the (line, col) with string part