use std::ffi::OsString;
use std::path::PathBuf;
use std::{error, fmt};
#[derive(Debug, PartialEq, Eq)]
pub enum XdgError {
HomeNotFound,
RelativePath {
env_var_key: &'static str,
path: PathBuf,
},
InvalidUnicode {
env_var_key: &'static str,
env_var_val: OsString,
},
}
impl fmt::Display for XdgError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
XdgError::HomeNotFound => formatter.write_str(
"Unable to retrieve user's home directory, neither HOME nor USER environment \
variable set",
),
XdgError::RelativePath { env_var_key, path } => formatter.write_fmt(format_args!(
"The `{env_var_key}` environment variable contains a relative path, while paths \
in XDG environment variables must be asbolute: `{path}`",
path = path.display()
)),
XdgError::InvalidUnicode { env_var_key, env_var_val } => {
formatter.write_fmt(format_args!(
"The `{env_var_key}` environment variable contains invalid unicode: \
{env_var_val:?}",
))
},
}
}
}
impl error::Error for XdgError {}
#[cfg(test)]
mod test {
use std::error::Error;
use std::ffi::OsStr;
use std::os::unix::prelude::OsStrExt;
use super::*;
const INVALID_UNICODE_BYTES: [u8; 4] = [0xF0, 0x90, 0x80, 0x67];
#[test]
fn display_error() -> Result<(), Box<dyn Error>> {
assert_eq!(
"Unable to retrieve user's home directory, neither HOME nor USER environment variable \
set",
XdgError::HomeNotFound.to_string()
);
assert_eq!(
"The `XDG_CONFIG_HOME` environment variable contains a relative path, while paths in \
XDG environment variables must be asbolute: `./config`",
XdgError::RelativePath {
env_var_key: "XDG_CONFIG_HOME",
path: PathBuf::from("./config"),
}
.to_string(),
);
assert_eq!(
"The `XDG_CONFIG_HOME` environment variable contains invalid unicode: \
\"\\xF0\\x90\\x80g\"",
XdgError::InvalidUnicode {
env_var_key: "XDG_CONFIG_HOME",
env_var_val: OsStr::from_bytes(&INVALID_UNICODE_BYTES).to_os_string(),
}
.to_string(),
);
Ok(())
}
}