1use crate::{db, store};
2use std::{array::TryFromSliceError, fmt, io};
3use thiserror::Error;
4
5pub type Result<T, E = Error> = std::result::Result<T, E>;
7
8#[derive(Debug, Error)]
9pub enum Error {
10 #[error("database error")]
12 Db(#[from] db::Error),
13 #[error("store error")]
14 Store(#[from] store::Error),
15 #[error("permission denied")]
16 PermissionDenied,
17 #[error("data is malformed")]
19 MalformedData,
20 #[error("invalid argument")]
21 InvalidArgument,
22 #[error("not a directory or directory malformed")]
23 MalformedDirectory,
24 #[error("entry already exists")]
25 EntryExists,
26 #[error("entry not found")]
27 EntryNotFound,
28 #[error("ambiguous entry")]
29 AmbiguousEntry,
30 #[error("entry is a file")]
31 EntryIsFile,
32 #[error("entry is a directory")]
33 EntryIsDirectory,
34 #[error("File name is not a valid UTF-8 string")]
35 NonUtf8FileName,
36 #[error("offset is out of range")]
37 OffsetOutOfRange,
38 #[error("directory is not empty")]
39 DirectoryNotEmpty,
40 #[error("operation is not supported")]
41 OperationNotSupported,
42 #[error("failed to write into writer")]
43 Writer(#[source] io::Error),
44 #[error("storage version mismatch")]
45 StorageVersionMismatch,
46 #[error("file or directory is locked")]
47 Locked,
48}
49
50impl Error {
51 pub fn verbose(&self) -> Verbose {
54 Verbose(self)
55 }
56}
57
58impl From<TryFromSliceError> for Error {
59 fn from(_: TryFromSliceError) -> Self {
60 Self::MalformedData
61 }
62}
63
64impl From<sqlx::Error> for Error {
65 fn from(src: sqlx::Error) -> Self {
66 Self::Db(src.into())
67 }
68}
69
70pub struct Verbose<'a>(&'a Error);
71
72impl fmt::Display for Verbose<'_> {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 use std::error::Error;
75
76 writeln!(f, "{}", self.0)?;
77
78 let mut current = self.0 as &dyn Error;
79
80 while let Some(source) = current.source() {
81 writeln!(f, " caused by: {}", source)?;
82 current = source;
83 }
84
85 Ok(())
86 }
87}