1use std::fmt::{Debug};
2use matchete::{Assessor, Resemblance};
3
4#[derive(Debug)]
5struct LevenshteinResembler;
6
7impl Resemblance<String, String> for LevenshteinResembler {
8 fn resemblance(&self, query: &String, candidate: &String) -> f64 {
9 let distance = levenshtein_distance(query, candidate);
10 let max_len = query.len().max(candidate.len());
11 if max_len == 0 { 1.0 } else { 1.0 - (distance as f64 / max_len as f64) }
12 }
13
14 fn perfect(&self, query: &String, candidate: &String) -> bool {
15 query == candidate
16 }
17}
18
19fn levenshtein_distance(a: &str, b: &str) -> usize {
20 let len_a = a.len();
21 let len_b = b.len();
22
23 if len_a == 0 { return len_b; }
24 if len_b == 0 { return len_a; }
25
26 let mut matrix = vec![vec![0; len_b + 1]; len_a + 1];
27
28 for i in 0..=len_a { matrix[i][0] = i; }
29 for j in 0..=len_b { matrix[0][j] = j; }
30
31 for i in 1..=len_a {
32 for j in 1..=len_b {
33 let cost = if a.chars().nth(i - 1) == b.chars().nth(j - 1) { 0 } else { 1 };
34 matrix[i][j] = (matrix[i - 1][j] + 1)
35 .min(matrix[i][j - 1] + 1)
36 .min(matrix[i - 1][j - 1] + cost);
37 }
38 }
39
40 matrix[len_a][len_b]
41}
42
43fn main() {
44 let assessor = Assessor::<String, String>::new()
45 .with(LevenshteinResembler, 1.0)
46 .floor(0.6);
47
48 let query = String::from("hello");
49 let candidates = vec![
50 String::from("hello"),
51 String::from("helo"),
52 String::from("world"),
53 ];
54
55 println!("Basic String Matching Example");
56 println!("============================");
57
58 if let Some(verdict) = assessor.champion(&query, &candidates) {
59 println!("Champion found:");
60 println!(" Resemblance: {:.2}", verdict.resemblance);
61 println!(" Candidate: {}", verdict.candidate);
62 println!(" Perfect: {}", verdict.perfect);
63 println!(" Disposition: {:?}", assessor.disposition(&query, &verdict.candidate));
64 } else {
65 println!("No viable candidate found above floor threshold");
66 }
67
68 println!("\nAll Candidates Analysis");
70 println!("======================");
71
72 for candidate in &candidates {
73 let verdict = assessor.verdict(&query, candidate);
74 let disposition = assessor.disposition(&query, candidate);
75 println!("'{}': resemblance={:.2}, disposition={:?}",
76 candidate, verdict.resemblance, disposition);
77 }
78}