Skip to main content

doublecrypt_core/
error.rs

1use thiserror::Error;
2
3/// Unified error type for the doublecrypt-core crate.
4#[derive(Debug, Error)]
5pub enum FsError {
6    #[error("block not found: {0}")]
7    BlockNotFound(u64),
8
9    #[error("block out of range: {0}")]
10    BlockOutOfRange(u64),
11
12    #[error("no free blocks available")]
13    NoFreeBlocks,
14
15    #[error("block size mismatch: expected {expected}, got {got}")]
16    BlockSizeMismatch { expected: usize, got: usize },
17
18    #[error("serialization error: {0}")]
19    Serialization(String),
20
21    #[error("deserialization error: {0}")]
22    Deserialization(String),
23
24    #[error("encryption error: {0}")]
25    Encryption(String),
26
27    #[error("decryption error: {0}")]
28    Decryption(String),
29
30    #[error("object not found: block {0}")]
31    ObjectNotFound(u64),
32
33    #[error("file not found: {0}")]
34    FileNotFound(String),
35
36    #[error("directory not found: {0}")]
37    DirectoryNotFound(String),
38
39    #[error("file already exists: {0}")]
40    FileAlreadyExists(String),
41
42    #[error("directory already exists: {0}")]
43    DirectoryAlreadyExists(String),
44
45    #[error("not a file: {0}")]
46    NotAFile(String),
47
48    #[error("not a directory: {0}")]
49    NotADirectory(String),
50
51    #[error("directory not empty: {0}")]
52    DirectoryNotEmpty(String),
53
54    #[error("name too long: {0} bytes (max {1})")]
55    NameTooLong(usize, usize),
56
57    #[error("filesystem not initialized")]
58    NotInitialized,
59
60    #[error("invalid superblock")]
61    InvalidSuperblock,
62
63    #[error("invalid root pointer")]
64    InvalidRootPointer,
65
66    #[error("data too large for single block: {0} bytes")]
67    DataTooLarge(usize),
68
69    #[error("internal error: {0}")]
70    Internal(String),
71}
72
73pub type FsResult<T> = Result<T, FsError>;
74
75/// Integer error codes for the C ABI layer.
76#[repr(i32)]
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub enum FsErrorCode {
79    Ok = 0,
80    NotFound = -1,
81    AlreadyExists = -2,
82    NoSpace = -3,
83    InvalidArgument = -4,
84    NotInitialized = -5,
85    IoError = -6,
86    CryptoError = -7,
87    InternalError = -8,
88    BufferTooSmall = -9,
89    NotAFile = -10,
90    NotADirectory = -11,
91    DirectoryNotEmpty = -12,
92    NameTooLong = -13,
93}
94
95impl From<&FsError> for FsErrorCode {
96    fn from(e: &FsError) -> Self {
97        match e {
98            FsError::BlockNotFound(_) | FsError::ObjectNotFound(_) => FsErrorCode::NotFound,
99            FsError::FileNotFound(_) | FsError::DirectoryNotFound(_) => FsErrorCode::NotFound,
100            FsError::FileAlreadyExists(_) | FsError::DirectoryAlreadyExists(_) => {
101                FsErrorCode::AlreadyExists
102            }
103            FsError::NoFreeBlocks => FsErrorCode::NoSpace,
104            FsError::BlockOutOfRange(_) | FsError::BlockSizeMismatch { .. } => {
105                FsErrorCode::InvalidArgument
106            }
107            FsError::DataTooLarge(_) => FsErrorCode::NoSpace,
108            FsError::NotInitialized | FsError::InvalidSuperblock | FsError::InvalidRootPointer => {
109                FsErrorCode::NotInitialized
110            }
111            FsError::Encryption(_) | FsError::Decryption(_) => FsErrorCode::CryptoError,
112            FsError::Serialization(_) | FsError::Deserialization(_) => FsErrorCode::InternalError,
113            FsError::NotAFile(_) => FsErrorCode::NotAFile,
114            FsError::NotADirectory(_) => FsErrorCode::NotADirectory,
115            FsError::DirectoryNotEmpty(_) => FsErrorCode::DirectoryNotEmpty,
116            FsError::NameTooLong(_, _) => FsErrorCode::NameTooLong,
117            FsError::Internal(_) => FsErrorCode::InternalError,
118        }
119    }
120}