use dictutils::prelude::*;
use std::fs;
use std::io::Write;
use std::path::Path;
fn main() -> dictutils::Result<()> {
println!("DictUtils Basic Dictionary Loading Example");
println!("==========================================");
let temp_dir = std::env::temp_dir();
let test_dict_path = temp_dir.join("example_dict.mdict");
create_example_dictionary(&test_dict_path)?;
println!("Created test dictionary at: {}", test_dict_path.display());
example_basic_loading(&test_dict_path)?;
example_format_detection(&test_dict_path)?;
example_key_lookups(&test_dict_path)?;
example_metadata_extraction(&test_dict_path)?;
example_error_handling()?;
let _ = fs::remove_file(&test_dict_path);
println!("\nBasic dictionary loading example completed successfully!");
Ok(())
}
fn example_basic_loading(path: &Path) -> dictutils::Result<()> {
println!("\n1. Basic Dictionary Loading");
println!("----------------------------");
let loader = DictLoader::new();
println!("Loading dictionary from: {}", path.display());
let mut dict = loader.load(path)?;
println!("✓ Dictionary loaded successfully");
println!(" Format: MDict");
println!(" Entries: {}", dict.len());
Ok(())
}
fn example_format_detection(path: &Path) -> dictutils::Result<()> {
println!("\n2. Format Detection");
println!("-------------------");
let loader = DictLoader::new();
let format = loader.detect_format(path)?;
println!("Detected format: {}", format);
let is_dict = loader.is_dictionary_file(path);
println!("Is valid dictionary: {}", is_dict);
let formats = loader.supported_formats();
println!("Supported formats: {:?}", formats);
Ok(())
}
fn example_key_lookups(path: &Path) -> dictutils::Result<()> {
println!("\n3. Key Lookup Operations");
println!("-------------------------");
let loader = DictLoader::new();
let mut dict = loader.load(path)?;
let test_keys = vec![
"hello",
"world",
"dictionary",
"rust",
"example",
"nonexistent_key",
];
for key in test_keys {
println!("\nLooking up key: '{}'", key);
match dict.get(&key.to_string()) {
Ok(entry) => {
let content = String::from_utf8_lossy(&entry);
println!("✓ Found: {}", content);
}
Err(DictError::IndexError(msg)) => {
println!("✗ Key not found: {}", msg);
}
Err(e) => {
println!("✗ Error: {}", e);
}
}
match dict.contains(&key.to_string()) {
Ok(exists) => {
println!(" Contains key: {}", if exists { "Yes" } else { "No" });
}
Err(e) => {
println!(" Error checking existence: {}", e);
}
}
}
Ok(())
}
fn example_metadata_extraction(path: &Path) -> dictutils::Result<()> {
println!("\n4. Metadata Extraction");
println!("----------------------");
let loader = DictLoader::new();
let dict = loader.load(path)?;
let metadata = dict.metadata();
println!("Dictionary Information:");
println!(" Name: {}", metadata.name);
println!(" Version: {}", metadata.version);
println!(" Entries: {}", metadata.entries);
println!(" File Size: {} bytes", metadata.file_size);
if let Some(ref description) = metadata.description {
println!(" Description: {}", description);
}
if let Some(ref author) = metadata.author {
println!(" Author: {}", author);
}
if let Some(ref language) = metadata.language {
println!(" Language: {}", language);
}
if let Some(ref created) = metadata.created {
println!(" Created: {}", created);
}
println!(" Has B-TREE Index: {}", metadata.has_btree);
println!(" Has FTS Index: {}", metadata.has_fts);
let stats = dict.stats();
println!("\nPerformance Statistics:");
println!(" Total Entries: {}", stats.total_entries);
println!(" Memory Usage: {} bytes", stats.memory_usage);
println!(" Cache Hit Rate: {:.2}%", stats.cache_hit_rate * 100.0);
println!(" Index Sizes:");
for (index_name, size) in &stats.index_sizes {
println!(" {}: {} bytes", index_name, size);
}
Ok(())
}
fn example_error_handling() -> dictutils::Result<()> {
println!("\n5. Error Handling Examples");
println!("--------------------------");
let loader = DictLoader::new();
println!("\nTest: Loading non-existent file");
let non_existent_path = Path::new("nonexistent.mdict");
match loader.load(non_existent_path) {
Ok(_) => println!("✗ Unexpected success"),
Err(DictError::FileNotFound(path)) => {
println!("✓ Correctly caught file not found: {}", path);
}
Err(e) => {
println!("✗ Unexpected error: {}", e);
}
}
println!("\nTest: Loading invalid format file");
let temp_dir = std::env::temp_dir();
let invalid_path = temp_dir.join("invalid_format.txt");
fs::write(&invalid_path, "This is not a dictionary file")?;
match loader.load(&invalid_path) {
Ok(_) => println!("✗ Unexpected success"),
Err(DictError::InvalidFormat(msg)) => {
println!("✓ Correctly caught invalid format: {}", msg);
}
Err(e) => {
println!("✗ Unexpected error: {}", e);
}
}
let _ = fs::remove_file(&invalid_path);
println!("\nTest: Loading directory instead of file");
let temp_path = temp_dir.join("test_directory");
fs::create_dir(&temp_path)?;
match loader.load(&temp_path) {
Ok(_) => println!("✗ Unexpected success"),
Err(DictError::FileNotFound(_)) => {
println!("✓ Correctly caught directory issue");
}
Err(e) => {
println!("✗ Unexpected error: {}", e);
}
}
let _ = fs::remove_dir(&temp_path);
Ok(())
}
fn create_example_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 = 6;
file.write_all(&entry_count.to_le_bytes())?;
let key_index_offset: u64 = 64;
let value_index_offset: u64 = 128;
let key_block_offset: u64 = 256;
let value_block_offset: u64 = 512;
file.write_all(&key_index_offset.to_le_bytes())?;
file.write_all(&value_index_offset.to_le_bytes())?;
file.write_all(&key_block_offset.to_le_bytes())?;
file.write_all(&value_block_offset.to_le_bytes())?;
let encoding: u32 = 0;
file.write_all(&encoding.to_le_bytes())?;
let compression: u32 = 0;
file.write_all(&compression.to_le_bytes())?;
let file_size = file.metadata()?.len();
file.write_all(&file_size.to_le_bytes())?;
let checksum: u32 = 12345;
file.write_all(&checksum.to_le_bytes())?;
let metadata_count: u32 = 3;
file.write_all(&metadata_count.to_le_bytes())?;
write_string_field(&mut file, "name", "Example Dictionary")?;
write_string_field(&mut file, "author", "DictUtils Example")?;
write_string_field(&mut file, "language", "English")?;
let entries = vec![
("hello", "Hello world! A greeting in English."),
("world", "The Earth and its inhabitants; the universe."),
(
"dictionary",
"A reference work that lists words and gives their meanings.",
),
(
"rust",
"A reddish-brown metal; also a programming language.",
),
(
"example",
"A thing characteristic of its kind or illustrating a general rule.",
),
(
"loading",
"The process of putting something into or onto a vehicle or container.",
),
];
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(())
}