use serde::de::DeserializeOwned;
use serde_json::Value;
pub type Result<T> = std::result::Result<T, ConfigError>;
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("configuration JSON parse error: {0}")]
Parse(#[source] serde_json::Error),
#[error("configuration root must be a JSON object")]
RootNotObject,
#[error("configuration file `{path}` read error: {source}")]
ReadFile {
path: String,
#[source]
source: std::io::Error,
},
#[error("configuration file `{path}` JSON parse error: {source}")]
ParseFile {
path: String,
#[source]
source: serde_json::Error,
},
#[error("configuration file `{path}` root must be a JSON object")]
FileRootNotObject {
path: String,
},
#[error("configuration deserialize error: {0}")]
Deserialize(#[from] serde_json::Error),
#[error("configuration deserialize error at `{path}`: {source}")]
ValueDeserialize {
path: String,
#[source]
source: serde_json::Error,
},
#[error("missing required configuration value `{path}`")]
MissingValue {
path: String,
},
}
pub(crate) fn deserialize_value<T>(path: String, value: &Value) -> Result<T>
where
T: DeserializeOwned,
{
T::deserialize(value).map_err(|source| ConfigError::ValueDeserialize { path, source })
}