fuzzy-cmp

Crates.iofuzzy-cmp
lib.rsfuzzy-cmp
version0.1.3
created_at2026-01-01 14:28:17.542023+00
updated_at2026-01-10 07:27:40.660372+00
descriptionFuzzy string matching library using Levenshtein distance.
homepage
repositoryhttps://github.com/fuderis/rs-fuzzy-cmp
max_upload_size
id2016273
size16,188
Bulat Sh. (fuderis)

documentation

README

githubcrates-iodocs-rs

Fuzzy Compare

Rust library for fuzzy string matching using Levenshtein distance. Returns results with similarity coefficient (0.0 = 0%, 1.0 = 100%) sorted from best to worst match. Supports deep word search.

Features:

  • Performance: O(n × L²) where L is average string length.

  • Case-insensitive: With automatic lowercase conversion.

  • Safe: Handles empty strings, division by zero.

  • Generic: Works with any Clone type via closure.

  • Sorting: Descending sort by coefficient.

Examples:

Deep compare:

fn main() {
    let s1 = "hello world";
    let s2 = "hello my friend";
    let min_coef = 0.4;
    let coef = fuzzy_cmp::deep_compare(s1, s2, min_coef);

    println!("Coefficient: {min_coef}");
    println!("String1: {s1}");
    println!("String2: {s2}");
    println!("Result: {coef} or {:.2}%", coef * 100.0);

    // -> Coefficient: 0.4
    // -> String1: hello world
    // -> String2: hello my friend
    // -> Result: 0.6244444 or 62.44%
}

Deep search:

fn main() {
    let files = vec![
        "Metallica - Master of Puppets [Live 2024].mp3",
        "Metallica - Master of Pupets [Remix].mp3",
        "Metallica Nothing Else Matters [Live].mp3",
        "Led Zeppelin - Stairway to Heaven.mp3"
    ];
    let query = "metallica puppets";
    let min_coef = 0.45;
    let results = fuzzy_cmp::search(&files, query, min_coef, true); // deep=true
    
    println!("Deep file search (coef {min_coef}):");
    println!("Search files: {files:#?}");
    println!("Search query: {query}");

    println!("Results: ");
    for (coef, file) in results.iter().take(3) {
        println!("  {:.2}% → {}", coef * 100.0, file);
    }

    // -> Deep file search (coef 0.45):
    // -> Search files: [
    // ->     "Metallica - Master of Puppets [Live 2024].mp3",
    // ->     "Metallica - Master of Pupets [Remix].mp3",
    // ->     "Metallica Nothing Else Matters [Live].mp3",
    // ->     "Led Zeppelin - Stairway to Heaven.mp3",
    // -> ]
    // -> Search query: metallica puppets
    // -> Results:
    // ->   111.06% → Metallica - Master of Puppets [Live 2024].mp3
    // ->   107.99% → Metallica - Master of Pupets [Remix].mp3
    // ->   71.77% → Metallica Nothing Else Matters [Live].mp3
}

Search struct:

#[derive(Debug, Clone, Eq, PartialEq)]
struct Person {
    name: String,
    age: u32,
}

fn main() {
    let people = vec![
        Person { name: "Alice".to_owned(), age: 30 },
        Person { name: "Bob".to_owned(), age: 25 },
        Person { name: "Alicia".to_owned(), age: 28 },
    ];

    let results = fuzzy_cmp::search_filter(&people, "Ali", 0.6, false, |p: &Person| &p.name);
    let best = &results[0];
    
    println!("Best result: {:.2}% -> {:?}", best.0 * 100.0, best.1);
    assert_eq!(best.1, Person { name: "Alice".to_owned(), age: 30 });

    // -> Best result: 60.00% -> Person { name: "Alice", age: 30 }
}

Licensing:

Distributed under the MIT license.

Feedback:

You can find me here, also see my channel. I welcome your suggestions and feedback!

Copyright (c) 2025 Bulat Sh. (fuderis)

Commit count: 11

cargo fmt