1use std::fmt;
4
5#[derive(Debug)]
7#[non_exhaustive]
8pub enum HoraError {
9 Io(std::io::Error),
12 CorruptedFile {
14 page: u32,
16 expected_checksum: u32,
18 actual_checksum: u32,
20 },
21 InvalidFile {
23 reason: &'static str,
25 },
26 VersionMismatch {
28 file_version: u16,
30 min_supported: u16,
32 max_supported: u16,
34 },
35
36 EntityNotFound(u64),
39 EdgeNotFound(u64),
41 DimensionMismatch {
43 expected: usize,
45 got: usize,
47 },
48 AlreadyInvalidated(u64),
50
51 StringTooLong {
54 max: usize,
56 got: usize,
58 },
59 StorageFull,
61
62 #[cfg(feature = "sqlite")]
65 Sqlite(String),
66
67 #[cfg(feature = "postgres")]
70 Postgres(String),
71}
72
73impl fmt::Display for HoraError {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 match self {
76 Self::Io(e) => write!(f, "I/O error: {}", e),
77 Self::CorruptedFile {
78 page,
79 expected_checksum,
80 actual_checksum,
81 } => write!(
82 f,
83 "corrupted page {}: expected checksum 0x{:08x}, got 0x{:08x}",
84 page, expected_checksum, actual_checksum
85 ),
86 Self::InvalidFile { reason } => write!(f, "invalid .hora file: {}", reason),
87 Self::VersionMismatch {
88 file_version,
89 min_supported,
90 max_supported,
91 } => write!(
92 f,
93 "version {} not supported (supported: {}-{})",
94 file_version, min_supported, max_supported
95 ),
96 Self::EntityNotFound(id) => write!(f, "entity {} not found", id),
97 Self::EdgeNotFound(id) => write!(f, "edge {} not found", id),
98 Self::DimensionMismatch { expected, got } => {
99 write!(
100 f,
101 "embedding dimension mismatch: expected {}, got {}",
102 expected, got
103 )
104 }
105 Self::AlreadyInvalidated(id) => write!(f, "fact {} is already invalidated", id),
106 Self::StringTooLong { max, got } => {
107 write!(f, "string too long: max {} bytes, got {}", max, got)
108 }
109 Self::StorageFull => write!(f, "storage is full"),
110 #[cfg(feature = "sqlite")]
111 Self::Sqlite(msg) => write!(f, "SQLite error: {}", msg),
112 #[cfg(feature = "postgres")]
113 Self::Postgres(msg) => write!(f, "PostgreSQL error: {}", msg),
114 }
115 }
116}
117
118impl std::error::Error for HoraError {
119 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
120 match self {
121 Self::Io(e) => Some(e),
122 _ => None,
123 }
124 }
125}
126
127impl From<std::io::Error> for HoraError {
128 fn from(e: std::io::Error) -> Self {
129 Self::Io(e)
130 }
131}
132
133pub type Result<T> = std::result::Result<T, HoraError>;