1use std::fmt;
4use std::path::PathBuf;
5
6#[derive(Debug)]
8pub enum Error {
9 Store(omgbase_store::Error),
11 Io {
13 what: String,
14 path: PathBuf,
15 source: std::io::Error,
16 },
17 Json(serde_json::Error),
19 RepoNotFound {
21 message: String,
22 candidates: Vec<String>,
23 },
24 AdapterSpawn { command: String, message: String },
26 AdapterExited { command: String },
28 AdapterHandshake { command: String, line: String },
30 AdapterError { method: String, message: String },
32 Unsupported(String),
35 WriterLockTimeout {
37 lock_path: PathBuf,
38 holder_pid: Option<i64>,
39 },
40 Other(String),
42}
43
44impl fmt::Display for Error {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 Error::Store(e) => write!(f, "store: {e}"),
48 Error::Io { what, path, source } => write!(f, "{what} {}: {source}", path.display()),
49 Error::Json(e) => write!(f, "json: {e}"),
50 Error::RepoNotFound { message, .. } => f.write_str(message),
51 Error::AdapterSpawn { command, message } => {
52 write!(f, "sync adapter '{command}' failed to spawn: {message}")
53 }
54 Error::AdapterExited { command } => {
55 write!(f, "sync adapter '{command}' exited early")
56 }
57 Error::AdapterHandshake { command, line } => {
58 let shown: String = line.chars().take(120).collect();
59 write!(
60 f,
61 "sync adapter '{command}' sent an invalid handshake: {shown}"
62 )
63 }
64 Error::AdapterError { method, message } => {
65 write!(f, "sync adapter error ({method}): {message}")
66 }
67 Error::Unsupported(what) => write!(f, "the source does not support {what}"),
68 Error::WriterLockTimeout {
69 lock_path,
70 holder_pid,
71 } => write!(
72 f,
73 "could not acquire writer lock {} (held by pid {})",
74 lock_path.display(),
75 holder_pid.map_or_else(|| "?".to_owned(), |p| p.to_string())
76 ),
77 Error::Other(msg) => f.write_str(msg),
78 }
79 }
80}
81
82impl std::error::Error for Error {
83 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
84 match self {
85 Error::Store(e) => Some(e),
86 Error::Io { source, .. } => Some(source),
87 Error::Json(e) => Some(e),
88 _ => None,
89 }
90 }
91}
92
93impl From<omgbase_store::Error> for Error {
94 fn from(e: omgbase_store::Error) -> Self {
95 Error::Store(e)
96 }
97}
98
99impl From<rusqlite::Error> for Error {
100 fn from(e: rusqlite::Error) -> Self {
101 Error::Store(omgbase_store::Error::Sqlite(e))
102 }
103}
104
105impl From<serde_json::Error> for Error {
106 fn from(e: serde_json::Error) -> Self {
107 Error::Json(e)
108 }
109}
110
111impl Error {
112 pub(crate) fn io(what: &str, path: impl Into<PathBuf>, source: std::io::Error) -> Self {
114 Error::Io {
115 what: what.to_owned(),
116 path: path.into(),
117 source,
118 }
119 }
120}
121
122pub type Result<T> = std::result::Result<T, Error>;