use dictutils::prelude::*;
use std::fs;
use std::io::Write;
use std::path::Path;
use std::time::Instant;
fn main() -> dictutils::Result<()> {
println!("DictUtils Search Operations Example");
println!("===================================");
let temp_dir = std::env::temp_dir();
let test_dict_path = temp_dir.join("search_example.mdict");
create_searchable_dictionary(&test_dict_path)?;
println!(
"Created searchable dictionary at: {}",
test_dict_path.display()
);
example_prefix_search(&test_dict_path)?;
example_fuzzy_search(&test_dict_path)?;
example_fulltext_search(&test_dict_path)?;
example_search_optimization(&test_dict_path)?;
example_advanced_search(&test_dict_path)?;
let _ = fs::remove_file(&test_dict_path);
println!("\nSearch operations example completed successfully!");
Ok(())
}
fn example_prefix_search(path: &Path) -> dictutils::Result<()> {
println!("\n1. Prefix Search Operations");
println!("---------------------------");
let loader = DictLoader::new();
let mut dict = loader.load(path)?;
let prefixes = vec!["com", "comp", "compu", "prog", "lang", "rust", "dat"];
for prefix in prefixes {
println!("\nSearching for prefix: '{}'", prefix);
let start_time = Instant::now();
match dict.search_prefix(prefix, Some(5)) {
Ok(results) => {
let duration = start_time.elapsed();
println!(
"✓ Found {} results in {:.2}ms",
results.len(),
duration.as_millis()
);
for (i, result) in results.iter().enumerate() {
let content = String::from_utf8_lossy(&result.entry);
println!(" {}. {} - {}", i + 1, result.word, content);
}
}
Err(e) => {
println!("✗ Search failed: {}", e);
}
}
}
Ok(())
}
fn example_fuzzy_search(path: &Path) -> dictutils::Result<()> {
println!("\n2. Fuzzy Search Operations");
println!("--------------------------");
let loader = DictLoader::new();
let mut dict = loader.load(path)?;
let fuzzy_queries = vec![
("computer", 2), ("compter", 2), ("programmin", 2), ("languag", 1), ("dictionary", 1), ("dictonary", 2), ];
for (query, max_distance) in fuzzy_queries {
println!(
"\nFuzzy searching for: '{}' (max distance: {})",
query, max_distance
);
let start_time = Instant::now();
match dict.search_fuzzy(query, Some(max_distance)) {
Ok(results) => {
let duration = start_time.elapsed();
println!(
"✓ Found {} results in {:.2}ms",
results.len(),
duration.as_millis()
);
for (i, result) in results.iter().enumerate() {
let content = String::from_utf8_lossy(&result.entry);
let score = result.score.map_or(0.0, |s| s);
println!(
" {}. {} (score: {:.3}) - {}",
i + 1,
result.word,
score,
content
);
}
}
Err(e) => {
println!("✗ Fuzzy search failed: {}", e);
}
}
}
Ok(())
}
fn example_fulltext_search(path: &Path) -> dictutils::Result<()> {
println!("\n3. Full-Text Search Operations");
println!("------------------------------");
let loader = DictLoader::new();
let mut dict = loader.load(path)?;
dict.build_indexes()?;
let fulltext_queries = vec![
"programming language",
"computer system",
"data structure",
"algorithm design",
"software development",
"database management",
];
for query in fulltext_queries {
println!("\nFull-text searching for: '{}'", query);
let start_time = Instant::now();
match dict.search_fulltext(query) {
Ok(iterator) => {
let results: dictutils::Result<Vec<_>> = iterator.collect();
match results {
Ok(results) => {
let duration = start_time.elapsed();
println!(
"✓ Found {} results in {:.2}ms",
results.len(),
duration.as_millis()
);
for (i, result) in results.iter().enumerate() {
let content = String::from_utf8_lossy(&result.entry);
let score = result.score.map_or(0.0, |s| s);
println!(" {}. {} (score: {:.3})", i + 1, result.word, score);
println!(" Content: {}", content);
}
}
Err(e) => {
println!("✗ Failed to collect results: {}", e);
}
}
}
Err(e) => {
println!("✗ Full-text search failed: {}", e);
}
}
}
Ok(())
}
fn example_search_optimization(path: &Path) -> dictutils::Result<()> {
println!("\n4. Search Optimization");
println!("---------------------");
let loader = DictLoader::new();
let mut dict = loader.load(path)?;
println!("Optimizing search with indexes...");
let start_time = Instant::now();
dict.build_indexes()?;
let build_time = start_time.elapsed();
println!("✓ Indexes built in {:.2}ms", build_time.as_millis());
let search_terms = vec!["comp", "prog", "lang", "dat"];
println!("\nSearch performance comparison:");
for term in search_terms {
let start = Instant::now();
match dict.search_prefix(term, Some(3)) {
Ok(results) => {
let duration = start.elapsed();
println!(
" '{}' - {} results in {:.2}ms",
term,
results.len(),
duration.as_millis()
);
}
Err(e) => {
println!(" '{}' - Search failed: {}", term, e);
}
}
}
let stats = dict.stats();
println!("\nIndex Statistics:");
println!(" Total Entries: {}", stats.total_entries);
println!(" Memory Usage: {} bytes", stats.memory_usage);
for (index_name, size) in &stats.index_sizes {
println!(" {} Index: {} bytes", index_name, size);
}
Ok(())
}
fn example_advanced_search(path: &Path) -> dictutils::Result<()> {
println!("\n5. Advanced Search Techniques");
println!("-----------------------------");
let loader = DictLoader::new();
let mut dict = loader.load(path)?;
println!("\nCombining search types:");
let prefix = "comp";
println!("\nStep 1: Prefix search for '{}'", prefix);
let prefix_results = dict.search_prefix(prefix, Some(10))?;
let candidate_keys: Vec<String> = prefix_results.iter().map(|r| r.word.clone()).collect();
println!("Found {} candidate keys", candidate_keys.len());
println!("\nStep 2: Fuzzy search on candidates");
let fuzzy_results = dict.search_fuzzy("computer", Some(2))?;
for result in fuzzy_results.iter().take(3) {
let content = String::from_utf8_lossy(&result.entry);
let score = result.score.map_or(0.0, |s| s);
println!(" {} (score: {:.3}) - {}", result.word, score, content);
}
println!("\nStep 3: Range query");
if let Ok(range_results) = dict.get_range(0..5) {
println!("First 5 entries:");
for (i, (key, value)) in range_results.iter().enumerate() {
let content = String::from_utf8_lossy(value);
println!(" {}. {} - {}", i + 1, key, content);
}
}
println!("\nStep 4: Iterated search with filtering");
let iterator = dict.iter()?;
let mut filtered_count = 0;
for entry_result in iterator {
match entry_result {
Ok((key, value)) => {
if key.contains("program") || String::from_utf8_lossy(&value).contains("program") {
println!(
" Filtered match: {} - {}",
key,
String::from_utf8_lossy(&value)
);
filtered_count += 1;
}
}
Err(e) => {
println!(" Iterator error: {}", e);
break;
}
}
}
println!("Found {} filtered entries", filtered_count);
Ok(())
}
fn create_searchable_dictionary(path: &Path) -> dictutils::Result<()> {
let mut file = fs::File::create(path)?;
let header = b"MDict\x00";
file.write_all(header)?;
let version = b"Version 1.0.0\x00\x00";
file.write_all(version)?;
let entry_count: u64 = 20;
file.write_all(&entry_count.to_le_bytes())?;
let offsets = [100u64, 150, 200, 250];
for offset in offsets {
file.write_all(&offset.to_le_bytes())?;
}
let encoding: u32 = 0; let compression: u32 = 0; file.write_all(&encoding.to_le_bytes())?;
file.write_all(&compression.to_le_bytes())?;
let file_size: u64 = 1024;
let checksum: u32 = 54321;
file.write_all(&file_size.to_le_bytes())?;
file.write_all(&checksum.to_le_bytes())?;
let metadata_count: u32 = 4;
file.write_all(&metadata_count.to_le_bytes())?;
write_string_field(&mut file, "name", "Search Example Dictionary")?;
write_string_field(&mut file, "author", "DictUtils Example")?;
write_string_field(&mut file, "language", "English")?;
write_string_field(
&mut file,
"description",
"Dictionary with rich content for search testing",
)?;
let entries = vec![
("computer", "A computer is an electronic device that can store, retrieve, and process data according to a set of instructions called a program."),
("programming", "Programming is the process of creating a set of instructions that tell a computer how to perform a task."),
("compiler", "A compiler is a computer program that transforms source code written in a programming language into computer machine language."),
("database", "A database is an organized collection of structured information, or data, typically stored electronically in a computer system."),
("algorithm", "An algorithm is a set of well-defined instructions in sequence to solve a problem or perform a task."),
("language", "A language is a structured system of communication used by humans, consisting of words, grammar, and pronunciation."),
("software", "Software is a collection of instructions and data that tell the computer how to work."),
("development", "Development is the process of creating software, applications, or systems through programming and design."),
("system", "A system is a group of interacting or interrelated elements that act according to a set of rules to form a unified whole."),
("data", "Data is any sequence of one or more symbols that carries meaning and can be interpreted by a computer."),
("structure", "A structure is an arrangement and organization of interrelated elements in a material object or system."),
("design", "Design is the creation of a plan or convention for the construction of an object, system, or measurable human activity."),
("management", "Management involves the organization, coordination, and supervision of complex, heavy or dynamic activities."),
("processing", "Processing is the manipulation or transformation of data to produce useful information or results."),
("machine", "A machine is a physical system that uses power to apply forces and control movement to perform an intended action."),
("network", "A network is a group of interconnected computers that can communicate and share resources with each other."),
("security", "Security is the protection of information and systems from unauthorized access, use, disclosure, disruption, modification, or destruction."),
("optimization", "Optimization is the action of making something as effective as possible, especially by making the best use of available resources."),
("integration", "Integration is the process of combining or coordinating separate elements into a unified whole system."),
("performance", "Performance refers to how well a computer system or software performs in terms of speed, efficiency, and reliability."),
];
for (key, _) in &entries {
write_string_field(&mut file, key, "")?;
}
for (_, value) in &entries {
write_string_field(&mut file, value, "")?;
}
Ok(())
}
fn write_string_field(file: &mut fs::File, key: &str, value: &str) -> dictutils::Result<()> {
use std::io::Write;
let key_bytes = key.as_bytes();
file.write_all(&(key_bytes.len() as u32).to_le_bytes())?;
file.write_all(key_bytes)?;
let value_bytes = value.as_bytes();
file.write_all(&(value_bytes.len() as u32).to_le_bytes())?;
file.write_all(value_bytes)?;
Ok(())
}