diff --git a/Cargo.lock b/Cargo.lock index 8cdca39..cfa620a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -914,7 +914,7 @@ dependencies = [ [[package]] name = "textdistance" -version = "1.0.0" +version = "1.0.1" dependencies = [ "assert2", "criterion", diff --git a/Cargo.toml b/Cargo.toml index 284b680..41d242f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "textdistance" -version = "1.0.0" +version = "1.0.1" edition = "2021" authors = ["Gram "] description = "Lots of algorithms to compare how similar two sequences are" diff --git a/src/algorithm.rs b/src/algorithm.rs index 5a536eb..8f15c9e 100644 --- a/src/algorithm.rs +++ b/src/algorithm.rs @@ -19,7 +19,7 @@ pub trait Algorithm { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + Hash, + E: Eq + Hash, { let s1: Vec = s1.collect(); let s2: Vec = s2.collect(); @@ -35,7 +35,7 @@ pub trait Algorithm { /// fn for_vec(&self, s1: &[E], s2: &[E]) -> Result where - E: Eq + Copy + Hash, + E: Eq + Hash, { self.for_iter(s1.iter(), s2.iter()) } diff --git a/src/algorithms/bag.rs b/src/algorithms/bag.rs index bb5fdf0..74cc5ed 100644 --- a/src/algorithms/bag.rs +++ b/src/algorithms/bag.rs @@ -13,7 +13,7 @@ impl Algorithm for Bag { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/cosine.rs b/src/algorithms/cosine.rs index 2a054f1..c6eefa8 100644 --- a/src/algorithms/cosine.rs +++ b/src/algorithms/cosine.rs @@ -15,7 +15,7 @@ impl Algorithm for Cosine { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/entropy_ncd.rs b/src/algorithms/entropy_ncd.rs index 0d3e3eb..99b7a2d 100644 --- a/src/algorithms/entropy_ncd.rs +++ b/src/algorithms/entropy_ncd.rs @@ -29,7 +29,7 @@ impl Default for EntropyNCD { } impl EntropyNCD { - fn compress(&self, c: &Counter) -> f64 { + fn compress(&self, c: &Counter) -> f64 { debug_assert!(self.correction >= 0.); let total_count = c.count(); let mut entropy = 0.0; @@ -46,7 +46,7 @@ impl Algorithm for EntropyNCD { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/jaccard.rs b/src/algorithms/jaccard.rs index 2ce8158..6c10ec7 100644 --- a/src/algorithms/jaccard.rs +++ b/src/algorithms/jaccard.rs @@ -17,7 +17,7 @@ impl Algorithm for Jaccard { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/jaro_winkler.rs b/src/algorithms/jaro_winkler.rs index 210b892..7974fb0 100644 --- a/src/algorithms/jaro_winkler.rs +++ b/src/algorithms/jaro_winkler.rs @@ -34,7 +34,7 @@ impl JaroWinkler { fn winklerize(&self, jaro: f64, s1: C, s2: C) -> f64 where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { debug_assert!(self.prefix_weight * self.max_prefix as f64 <= 1.0); let mut prefix_len = 0; @@ -55,7 +55,7 @@ impl JaroWinkler { impl Algorithm for JaroWinkler { fn for_vec(&self, s1: &[E], s2: &[E]) -> Result where - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let jaro = self.jaro.for_vec(s1, s2).nval(); Result { diff --git a/src/algorithms/lcsseq.rs b/src/algorithms/lcsseq.rs index 37fee84..2ab2cf4 100644 --- a/src/algorithms/lcsseq.rs +++ b/src/algorithms/lcsseq.rs @@ -11,7 +11,7 @@ use crate::{Algorithm, Result}; pub struct LCSSeq {} impl Algorithm for LCSSeq { - fn for_vec(&self, s1: &[E], s2: &[E]) -> Result { + fn for_vec(&self, s1: &[E], s2: &[E]) -> Result { let l1 = s1.len(); let l2 = s2.len(); let mut lengths = vec![vec![0; l2 + 1]; l1 + 1]; @@ -26,7 +26,7 @@ impl Algorithm for LCSSeq { } } - let mut result = Vec::::new(); + let mut result = Vec::<&E>::new(); let mut i = l1; let mut j = l2; while i != 0 && j != 0 { @@ -36,7 +36,7 @@ impl Algorithm for LCSSeq { j -= 1; } else { assert!(s1[i - 1] == s2[j - 1]); - result.push(s1[i - 1]); + result.push(&s1[i - 1]); i -= 1; j -= 1; } diff --git a/src/algorithms/lig3.rs b/src/algorithms/lig3.rs index d771a15..9984eed 100644 --- a/src/algorithms/lig3.rs +++ b/src/algorithms/lig3.rs @@ -31,7 +31,7 @@ impl Default for LIG3 { impl Algorithm for LIG3 { fn for_vec(&self, s1: &[E], s2: &[E]) -> Result where - E: Eq + Copy + Hash, + E: Eq + Hash, { let lev_res = self.levenshtein.for_vec(s1, s2); let lev = lev_res.dist(); diff --git a/src/algorithms/mlipns.rs b/src/algorithms/mlipns.rs index 1f1b43d..2c0ffd6 100644 --- a/src/algorithms/mlipns.rs +++ b/src/algorithms/mlipns.rs @@ -48,7 +48,7 @@ impl Algorithm for MLIPNS { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + Hash, + E: Eq + Hash, { let ham = self.hamming.for_iter(s1, s2); Result { diff --git a/src/algorithms/overlap.rs b/src/algorithms/overlap.rs index d114a52..7f80fcf 100644 --- a/src/algorithms/overlap.rs +++ b/src/algorithms/overlap.rs @@ -12,7 +12,7 @@ impl Algorithm for Overlap { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/roberts.rs b/src/algorithms/roberts.rs index 824c9cf..161b59c 100644 --- a/src/algorithms/roberts.rs +++ b/src/algorithms/roberts.rs @@ -14,7 +14,7 @@ impl Algorithm for Roberts { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/sorensen_dice.rs b/src/algorithms/sorensen_dice.rs index afd5ab0..e3b47c2 100644 --- a/src/algorithms/sorensen_dice.rs +++ b/src/algorithms/sorensen_dice.rs @@ -12,7 +12,7 @@ impl Algorithm for SorensenDice { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/tversky.rs b/src/algorithms/tversky.rs index a5e5117..e12908a 100644 --- a/src/algorithms/tversky.rs +++ b/src/algorithms/tversky.rs @@ -30,7 +30,7 @@ impl Algorithm for Tversky { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + std::hash::Hash, + E: Eq + std::hash::Hash, { let c1 = Counter::from_iter(s1); let c2 = Counter::from_iter(s2); diff --git a/src/algorithms/yujian_bo.rs b/src/algorithms/yujian_bo.rs index e6b39fb..b016ee5 100644 --- a/src/algorithms/yujian_bo.rs +++ b/src/algorithms/yujian_bo.rs @@ -1,7 +1,6 @@ //! Yujian-Bo distance use super::levenshtein::Levenshtein; use crate::{Algorithm, Result}; -use std::hash::Hash; /// [Yujian-Bo distance] is a normalization of [Levenshtein]. /// @@ -16,7 +15,7 @@ impl Algorithm for YujianBo { fn for_iter(&self, s1: C, s2: C) -> Result where C: Iterator, - E: Eq + Copy + Hash, + E: Eq + std::hash::Hash, { let lev = self.levenshtein.for_iter(s1, s2); let dc: usize = self.levenshtein.del_cost; diff --git a/src/counter.rs b/src/counter.rs index dd2e09c..1b7e26d 100644 --- a/src/counter.rs +++ b/src/counter.rs @@ -8,7 +8,7 @@ pub struct Counter { impl Counter where - K: Hash + Eq + Copy, + K: Hash + Eq, { /// make an empty Counter pub fn new() -> Counter { @@ -59,15 +59,15 @@ where } /// Merge two counters together. - pub fn merge(&self, rhs: &Counter) -> Counter { - let mut result: HashMap = HashMap::new(); + pub fn merge<'a>(&'a self, rhs: &'a Counter) -> Counter<&'a K> { + let mut result: HashMap<&K, usize> = HashMap::new(); for (key, lhs_count) in &self.map { let rhs_count = rhs.map.get(key).unwrap_or(&0); - result.insert(*key, *lhs_count + rhs_count); + result.insert(key, *lhs_count + rhs_count); } for (key, rhs_count) in &rhs.map { if self.map.get(key).is_none() { - result.insert(*key, *rhs_count); + result.insert(key, *rhs_count); } } Counter { map: result } @@ -118,7 +118,7 @@ mod tests { use assert2::assert; use rstest::rstest; - pub fn eq(lhs: &Counter, rhs: &Counter) -> bool { + pub fn eq(lhs: &Counter, rhs: &Counter) -> bool { for (key, lhs_count) in &lhs.map { if let Some(rhs_count) = rhs.map.get(key) { if lhs_count != rhs_count {