1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
//! 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);
//!}
//! ```
pub mod levenshtein;
pub mod search_engine;
pub mod similarity;
pub mod type_erasure;