rawdb/
error.rs

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    // Region errors
14    RegionNotFound,
15    RegionAlreadyExists,
16    RegionStillReferenced {
17        ref_count: usize,
18    },
19
20    // Write errors
21    WriteOutOfBounds {
22        position: u64,
23        region_len: u64,
24    },
25
26    // Truncate errors
27    TruncateInvalid {
28        from: u64,
29        current_len: u64,
30    },
31
32    // Metadata errors
33    InvalidRegionId,
34    InvalidMetadataSize {
35        expected: usize,
36        actual: usize,
37    },
38    EmptyMetadata,
39
40    // Layout errors
41    RegionIndexMismatch,
42
43    // Hole punching errors
44    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 {}