use std::path::PathBuf;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum BackendError {
#[error("Failed to open backend: {0}")]
Open(String),
#[error("Failed to read from backend: {0}")]
Read(String),
#[error("Failed to write to backend: {0}")]
Write(String),
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum SettingsError {
#[error(transparent)]
Backend(#[from] BackendError),
#[error("Failed to serialize persisted setting value: {source}")]
Serialize { source: serde_json::Error },
#[error("No configuration directory found.")]
NoConfigDir,
#[error("Failed to read config file `{path}`: {source}")]
ConfigRead {
path: PathBuf,
source: std::io::Error,
},
#[error("Failed to parse config file `{path}`: {source}")]
ConfigParse {
path: PathBuf,
source: toml::de::Error,
},
#[error("Failed to parse config value `{key}`: {source}")]
ConfigValueParse {
key: String,
source: toml::de::Error,
},
#[error("Failed to parse environment variable `{name}`: {source}")]
EnvParse {
name: String,
source: toml::de::Error,
},
#[error("Failed to parse persisted setting `{key}`: {source}")]
PersistValueParse {
key: String,
source: serde_json::Error,
},
#[error("Failed to parse persisted setting `{key}` with deserialize fallback: {error}")]
PersistFallbackParse { key: String, error: String },
}
#[cfg(test)]
mod tests {
use super::*;
use serde::{Serialize, Serializer};
struct FailingSerialize;
impl Serialize for FailingSerialize {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Err(serde::ser::Error::custom("intentional serialize failure"))
}
}
#[test]
fn test_backend_error_open_message_is_correct() {
let msg = String::from("test_message");
let error = BackendError::Open(msg.clone());
assert_eq!(
error.to_string(),
format!("Failed to open backend: {}", msg)
);
}
#[test]
fn test_backend_error_read_message_is_correct() {
let msg = String::from("test_message");
let error = BackendError::Read(msg.clone());
assert_eq!(
error.to_string(),
format!("Failed to read from backend: {}", msg)
);
}
#[test]
fn test_backend_error_write_message_is_correct() {
let msg = String::from("test_message");
let error = BackendError::Write(msg.clone());
assert_eq!(
error.to_string(),
format!("Failed to write to backend: {}", msg)
);
}
#[test]
fn test_settings_error_backend_message_is_correct() {
let msg = String::from("test_message");
let b_error = BackendError::Open(msg.clone());
let s_error = SettingsError::from(b_error);
assert_eq!(
s_error.to_string(),
format!("Failed to open backend: {}", msg)
);
}
#[test]
fn test_settings_error_serialize_message_is_correct() {
let source = serde_json::to_string(&FailingSerialize).unwrap_err();
let set_error = SettingsError::Serialize { source };
assert!(
set_error
.to_string()
.contains("Failed to serialize persisted setting value:")
)
}
#[test]
fn test_settings_error_noconfigdir_message_is_correct() {
let s_error = SettingsError::NoConfigDir;
assert_eq!(s_error.to_string(), "No configuration directory found.")
}
}