1use std::{
2 fmt::{self, Debug, Display},
3 fs, io, result,
4};
5
6pub type Result<T, E = Error> = result::Result<T, E>;
7
8#[derive(Debug)]
9pub enum Error {
10 IO(io::Error),
11 TryLock(fs::TryLockError),
12
13 RegionNotFound,
15 RegionAlreadyExists,
16 RegionStillReferenced {
17 ref_count: usize,
18 },
19
20 WriteOutOfBounds {
22 position: u64,
23 region_len: u64,
24 },
25
26 TruncateInvalid {
28 from: u64,
29 current_len: u64,
30 },
31
32 InvalidRegionId,
34 InvalidMetadataSize {
35 expected: usize,
36 actual: usize,
37 },
38 EmptyMetadata,
39
40 RegionIndexMismatch,
42
43 HolePunchFailed {
45 start: u64,
46 len: u64,
47 source: io::Error,
48 },
49}
50
51impl From<io::Error> for Error {
52 fn from(value: io::Error) -> Self {
53 Self::IO(value)
54 }
55}
56
57impl From<fs::TryLockError> for Error {
58 fn from(value: fs::TryLockError) -> Self {
59 Self::TryLock(value)
60 }
61}
62
63impl fmt::Display for Error {
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 match self {
66 Error::IO(error) => Display::fmt(&error, f),
67 Error::TryLock(_) => write!(f, "Database is locked by another process"),
68
69 Error::RegionNotFound => write!(f, "Region not found"),
70 Error::RegionAlreadyExists => write!(f, "Region already exists"),
71 Error::RegionStillReferenced { ref_count } => write!(
72 f,
73 "Cannot remove region: still held by {} reference(s)",
74 ref_count - 1
75 ),
76
77 Error::WriteOutOfBounds {
78 position,
79 region_len,
80 } => write!(
81 f,
82 "Write position {} is beyond region length {}",
83 position, region_len
84 ),
85
86 Error::TruncateInvalid { from, current_len } => write!(
87 f,
88 "Cannot truncate to {} bytes (current length: {})",
89 from, current_len
90 ),
91
92 Error::InvalidRegionId => write!(f, "Invalid region ID"),
93 Error::InvalidMetadataSize { expected, actual } => write!(
94 f,
95 "Invalid metadata size: expected {} bytes, got {}",
96 expected, actual
97 ),
98 Error::EmptyMetadata => write!(f, "Empty region metadata"),
99
100 Error::RegionIndexMismatch => write!(f, "Region index mismatch in layout"),
101
102 Error::HolePunchFailed { start, len, source } => write!(
103 f,
104 "Failed to punch hole at offset {} (length {}): {}",
105 start, len, source
106 ),
107 }
108 }
109}
110
111impl std::error::Error for Error {}