use serde::{Deserialize, Serialize}; use std::fmt::Display; use std::io; use std::path::Path; #[derive(thiserror::Error, Debug, Deserialize, Serialize, Clone)] #[error("Filesystem error while processing '{path}': {err}")] pub struct Error { err: String, path: String, } impl Error { pub fn new(err: impl Display, path: impl AsRef) -> Self { Error { err: err.to_string(), path: path.as_ref().to_string_lossy().to_string(), } } pub fn not_found(path: impl AsRef) -> Self { Error::new("Not found", path) } pub fn already_exists(path: impl AsRef) -> Self { Error::new("Already exists", path) } } impl From for Error { fn from(e: io::Error) -> Self { Error { err: e.to_string(), path: String::new(), } } } impl From for Error { fn from(e: anyhow::Error) -> Self { let err = e .chain() .rev() .skip(1) .map(|cause| format!("ctx: {}", cause)) .collect::>() .join("\n"); Error { err, path: String::new(), } } }