soft_canonicalize/
error.rs1use std::borrow::Cow;
2use std::path::{Path, PathBuf};
3use std::{fmt, io};
4
5#[derive(Debug, Clone)]
7pub struct SoftCanonicalizeError {
8 path: PathBuf,
9 detail: Cow<'static, str>,
10}
11
12impl SoftCanonicalizeError {
13 pub fn new(path: PathBuf, detail: impl Into<Cow<'static, str>>) -> Self {
14 Self {
15 path,
16 detail: detail.into(),
17 }
18 }
19 pub fn path(&self) -> &Path {
21 &self.path
22 }
23 pub fn detail(&self) -> &str {
25 &self.detail
26 }
27}
28
29impl fmt::Display for SoftCanonicalizeError {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "{} (path: '{}')", self.detail, self.path.display())
32 }
33}
34
35impl std::error::Error for SoftCanonicalizeError {}
36
37#[inline]
39pub(crate) fn error_with_path(
40 kind: io::ErrorKind,
41 path: &Path,
42 detail: impl Into<Cow<'static, str>>,
43) -> io::Error {
44 io::Error::new(kind, SoftCanonicalizeError::new(path.to_path_buf(), detail))
45}
46
47pub trait IoErrorPathExt {
49 fn offending_path(&self) -> Option<&Path>;
50 fn soft_canon_detail(&self) -> Option<&str>;
51}
52
53impl IoErrorPathExt for io::Error {
54 fn offending_path(&self) -> Option<&Path> {
55 self.get_ref()
56 .and_then(|e| e.downcast_ref::<SoftCanonicalizeError>())
57 .map(|p| p.path())
58 }
59
60 fn soft_canon_detail(&self) -> Option<&str> {
61 self.get_ref()
62 .and_then(|e| e.downcast_ref::<SoftCanonicalizeError>())
63 .map(|p| p.detail())
64 }
65}