simple_search 0.2.0

A simple library for searching objects
Documentation
# simple_search-rs

A simple library for searching objects.
## Basic Usage
 ```rust
 use simple_search::search_engine::SearchEngine;
 use simple_search::levenshtein::base::weighted_levenshtein_similarity;
fn main() {
     let engine = SearchEngine::new()
         .with_values(vec!["hello", "world", "foo", "bar"])
         .with(|v, q| weighted_levenshtein_similarity(v, q));
     let results = engine.search("hallo");
     println!("search for hallo: {:?}", results);
}
 ```
## Advanced Usage
The following example shows how to use the library with a custom type.
The [SearchEngine](simple_search::search_engine::SearchEngine) is configured to search for books by title, author and description.
Each of those is weighted differently and the [IncrementalLevenshtein](simple_search::levenshtein::incremental::IncrementalLevenshtein) is used to calculate the similarity.
```rust
use simple_search::search_engine::SearchEngine;
use simple_search::levenshtein::incremental::IncrementalLevenshtein;

#[derive(Debug)]
struct Book {
    title: String,
    description: String,
    author: String,
}

fn main() {
    let book1 = Book {
        title: "The Winds of Winter".to_string(),
        description: "The sixth book in the A Song of Ice and Fire series.".to_string(),
        author: "George R. R. Martin".to_string(),
    };
    let book2 = Book {
        title: "The Great Gatsby".to_string(),
        description: "A classic novel of the roaring twenties.".to_string(),
        author: "F. Scott Fitzgerald".to_string(),
    };
    let book3 = Book {
        title: "Brave New World".to_string(),
        description: "A visionary and disturbing novel about a dystopian future.".to_string(),
        author: "Aldous Huxley".to_string(),
    };
    let book4 = Book {
        title: "To Kill a Mockingbird".to_string(),
        description: "A novel that deals with issues like injustice and moral growth.".to_string(),
        author: "Harper Lee".to_string(),
    };
    
    let engine = SearchEngine::new()
        .with_values(vec![book1, book2, book3, book4])
        .with_state(
            |book| IncrementalLevenshtein::new("", &book.title),
            |s, _, q| s.weighted_similarity(q),
        )
        .with_state_and_weight(
            0.8,
            |book| IncrementalLevenshtein::new("", &book.author),
            |s, _, q| s.weighted_similarity(q),
        )
        .with_state_and_weight(
            0.5,
            |book| IncrementalLevenshtein::new("", &book.description),
            |s, _, q| s.weighted_similarity(q),
        );
    
    let mut engine = engine.erase_type();
    
    let results = engine.similarities("Fire adn water");
    
    println!("search for Fire and Ice:");
    for result in results {
        println!("{:?}", result);
    }
    
    println!();
    
    let results = engine.similarities("Fitzereld");
    
    println!("Fitzgerald");
    for result in results {
        println!("{:?}", result);
    }
    
    println!();
}
```
## Storing an engine
The [SearchEngine](simple_search::search_engine::SearchEngine) most often has a very complicated type, that can't easily be expressed.
To work around this, the [type_erasure](simple_search::type_erasure) module provides a way to store the engine, by using a trait object in a [Box](std::boxed::Box). \
This solution is not ideal, as it requires dynamic dispatch, but the overhead is minimal
Once the approved [RFC 2515](https://rust-lang.github.io/impl-trait-initiative/RFC.html) is part of stable rust, this will be replaced with a more elegant solution.
For more details on this see the [type_erasure](simple_search::type_erasure) module.
```rust
 use simple_search::search_engine::SearchEngine;
 use simple_search::levenshtein::incremental::IncrementalLevenshtein;
 use simple_search::type_erasure::non_cloneable::MutableSearchEngine;

 fn main() {
     let engine = SearchEngine::new()
         .with_values(vec!["hello", "world", "foo", "bar"])
         .with_state(
                 |v| IncrementalLevenshtein::new("", v),
                 |s, _, q| s.weighted_similarity(q),
         );
     
     let mut engine: MutableSearchEngine<&str, str> = engine.erase_type();
     
     let results = engine.search("hallo");
     println!("search for hallo: {:?}", results);
 }
 ```
## Parallelization
The [SearchEngine](simple_search::search_engine::SearchEngine) can be used in parallel, using [rayon](https://docs.rs/rayon/latest/rayon/) iterators.
This simply involved calling the parallel version of the respective function \
(As long as the values and query are [Send] + [Sync]).
 ```rust
 use simple_search::search_engine::SearchEngine;
 use simple_search::levenshtein::base::weighted_levenshtein_similarity;

fn main() {
     let engine = SearchEngine::new()
         .with_values(vec!["hello", "world", "foo", "bar"])
         .with(|v, q| weighted_levenshtein_similarity(v, q));
     let results = engine.par_search("hallo");
     println!("search for hallo: {:?}", results);
}
 ```