1#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum Error {
9 #[error("invalid configuration: {reason}. Fix: {fix}")]
11 InvalidConfig {
12 reason: String,
14 fix: String,
16 },
17
18 #[error("document too large: size={size}, max={max}. Fix: increase max_document_size in Config or filter large documents before deduplication.")]
20 DocumentTooLarge {
21 size: usize,
23 max: usize,
25 },
26
27 #[error("empty document at index {index}. Fix: filter empty documents before deduplication.")]
29 EmptyDocument {
30 index: usize,
32 },
33
34 #[error("hashing failed: {reason}. Fix: check for integer overflow or memory exhaustion.")]
36 HashingFailed {
37 reason: String,
39 },
40
41 #[error("memory limit exceeded: {usage_bytes} bytes. Fix: increase memory_limit_in_mb in Config or reduce num_bands.")]
43 MemoryLimitExceeded {
44 usage_bytes: u64,
46 },
47
48 #[error("io error: {0}. Fix: check file permissions and disk space.")]
50 Io(#[from] std::io::Error),
51}
52
53pub type Result<T> = std::result::Result<T, Error>;
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn error_display_includes_fix() {
62 let err = Error::InvalidConfig {
63 reason: "num_bands must divide signature_size".to_string(),
64 fix: "use a signature_size divisible by num_bands".to_string(),
65 };
66 let msg = err.to_string();
67 assert!(msg.contains("Fix:"));
68 assert!(msg.contains("signature_size"));
69 }
70
71 #[test]
72 fn document_too_large_error_includes_size() {
73 let err = Error::DocumentTooLarge {
74 size: 1000000,
75 max: 100000,
76 };
77 let msg = err.to_string();
78 assert!(msg.contains("1000000"));
79 assert!(msg.contains("100000"));
80 }
81}