Install simsearch via Cargo
mainTo use simsearch in your Rust project, add it to your Cargo.toml dependencies. The current compatible version is 0.4.
[dependencies]
simsearch = "0.4"repository·main·Indexed 41 days ago
https://github.com/andylokandy/simsearchA lightweight, in-memory fuzzy search index for Rust applications, designed for embedded autocomplete and search suggestions. Version 0.4.0 provides the Index<T> type for mapping unique identifiers to searchable strings, supporting multi-field indexing via insert_parts, Jaro-Winkler typo tolerance, and customizable search options including result limits and case sensitivity.
To use simsearch in your Rust project, add it to your Cargo.toml dependencies. The current compatible version is 0.4.
[dependencies]
simsearch = "0.4"The Index<T> type is the core of simsearch. It allows you to map unique identifiers of type T to string values for fuzzy searching.
Index::new()..insert(id, text), where id is your unique identifier and text is the string to be indexed..search(query), which returns a list of results containing the original id and a similarity score.use simsearch::Index;
let mut engine: Index<u32> = Index::new();
engine.insert(1, "Things Fall Apart");
engine.insert(2, "The Old Man and the Sea");
engine.insert(3, "James Joyce");
let results = engine.search("thngs");
assert_eq!(results[0].id, 1);
assert!(results[0].score > 0.0);You can explore the library's capabilities by running the built-in books example using cargo.
cargo run --release --example booksUse Index::with_options(options) to customize search behavior. The Options struct uses a builder pattern.
Available configuration methods:
limit(usize): Sets the maximum number of results returned (default: 10).prefix_search(bool): Enables/disables matching the last query token as a prefix (default: true).typo_tolerance(bool): Enables/disables Jaro-Winkler similarity for typo tolerance (default: true).case_sensitive(bool): Sets whether searches are case sensitive (default: false).separators(I): Adds additional characters to be treated as token separators alongside whitespace.use simsearch::{Index, Options};
let options = Options::new()
.limit(20)
.case_sensitive(true)
.separators(['/', '\', '.']);
let mut engine = Index::with_options(options);To manage the lifecycle of indexed data:
remove(&id): Removes the entry associated with the specific ID.clear(): Removes all entries and resets the internal ID counter.// Remove a specific item
engine.remove(&1);
// Wipe the entire index
engine.clear();The search(pattern) method returns a Vec<Hit<Id>> sorted by relevance.
Each Hit<Id> contains:
id: The original identifier associated with the match.score: A normalized relevance score in the 0.0..=1.0 range. Scores are relative; they are useful for comparing results within the same search query.let results = engine.search("martin");
for hit in results {
println!("ID: {:?}, Score: {}", hit.id, hit.score);
}You can add data to the index using two primary methods:
insert(id, content): Tokenizes a single string. By default, whitespace characters are separators.insert_parts(id, parts): Tokenizes multiple string parts (e.g., title, author, tags) and treats them as a single searchable entry for the given ID. This is useful for multi-field search.Note: The ID itself is not searchable. If you want the ID to be part of the search results, include it in the content string. Inserting an existing ID will update its content.
use simsearch::Index;
let mut engine: Index<&str> = Index::new();
// Single content insertion
engine.insert("item1", "A Game of Thrones");
// Multiple parts insertion (e.g., title and author)
engine.insert_parts("item2", [
"A Game of Thrones",
"George R. R. Martin",
"fantasy",
]);The Index<Id> is an in-memory fuzzy search engine. It allows you to map unique identifiers (Id) to searchable string content. You can create an index using default settings or provide custom Options.
use simsearch::Index;
// Create an index with default options
let mut engine: Index<u32> = Index::new();
// Insert data
engine.insert(1, "Things Fall Apart");
engine.insert(2, "The Old Man and the Sea");
// Perform a fuzzy search
let results = engine.search("thngs");
// Access results
if let Some(hit) = results.first() {
assert_eq!(hit.id, 1);
println!("Found {} with score {}", hit.id, hit.score);
}