mirror of
https://github.com/OMGeeky/confique.git
synced 2026-01-05 11:10:29 +01:00
Move error code to error.rs
This commit is contained in:
106
src/error.rs
Normal file
106
src/error.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use std::{ffi::OsString, fmt, path::PathBuf};
|
||||
|
||||
|
||||
/// Type describing all errors that can occur in this library.
|
||||
pub struct Error {
|
||||
pub(crate) inner: Box<ErrorInner>,
|
||||
}
|
||||
|
||||
pub(crate) enum ErrorInner {
|
||||
/// Returned by `Config::from_partial` when the partial does not contain
|
||||
/// values for all required configuration values. The string is a
|
||||
/// human-readable path to the value, e.g. `http.port`.
|
||||
MissingValue(String),
|
||||
|
||||
/// An IO error occured, e.g. when reading a file.
|
||||
Io {
|
||||
path: Option<PathBuf>,
|
||||
err: std::io::Error,
|
||||
},
|
||||
|
||||
/// Returned by `Source::load` implementations when deserialization fails.
|
||||
Deserialization {
|
||||
/// A human readable description for the error message, describing from
|
||||
/// what source it was attempted to deserialize. Completes the sentence
|
||||
/// "failed to deserialize configuration from ". E.g. "file 'foo.toml'"
|
||||
/// or "environment variable 'FOO_PORT'".
|
||||
source: Option<String>,
|
||||
err: Box<dyn std::error::Error + Send + Sync>,
|
||||
},
|
||||
|
||||
/// Returned by the [`Source`] impls for `Path` and `PathBuf` if the file
|
||||
/// extension is not supported by confique or if the corresponding Cargo
|
||||
/// feature of confique was not enabled.
|
||||
UnsupportedFileFormat {
|
||||
path: PathBuf,
|
||||
extension: OsString,
|
||||
},
|
||||
|
||||
/// Returned by the [`Source`] impls for `Path` and `PathBuf` if the path
|
||||
/// does not contain a file extension.
|
||||
MissingFileExtension {
|
||||
path: PathBuf,
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match &*self.inner {
|
||||
ErrorInner::Io { err, .. } => Some(err),
|
||||
ErrorInner::Deserialization { err, .. } => Some(&**err),
|
||||
ErrorInner::MissingValue(_)
|
||||
| ErrorInner::UnsupportedFileFormat { .. }
|
||||
| ErrorInner::MissingFileExtension { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match &*self.inner {
|
||||
ErrorInner::MissingValue(path) => {
|
||||
std::write!(f, "required configuration value is missing: '{}'", path)
|
||||
}
|
||||
ErrorInner::Io { path: Some(path), .. } => {
|
||||
std::write!(f,
|
||||
"IO error occured while reading configuration file '{}'",
|
||||
path.display(),
|
||||
)
|
||||
}
|
||||
ErrorInner::Io { path: None, .. } => {
|
||||
std::write!(f, "IO error occured while loading configuration")
|
||||
}
|
||||
ErrorInner::Deserialization { source: Some(source), .. } => {
|
||||
std::write!(f, "failed to deserialize configuration from {}", source)
|
||||
}
|
||||
ErrorInner::Deserialization { source: None, .. } => {
|
||||
std::write!(f, "failed to deserialize configuration")
|
||||
}
|
||||
ErrorInner::UnsupportedFileFormat { path, extension } => {
|
||||
std::write!(f,
|
||||
"unknown configuration file format '{}' of '{}'",
|
||||
extension.to_string_lossy(),
|
||||
path.display(),
|
||||
)
|
||||
}
|
||||
ErrorInner::MissingFileExtension { path } => {
|
||||
std::write!(f,
|
||||
"cannot guess configuration file format due to missing file extension in '{}'",
|
||||
path.display(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorInner> for Error {
|
||||
fn from(inner: ErrorInner) -> Self {
|
||||
Self { inner: Box::new(inner) }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{ffi::OsStr, fs, io, path::{Path, PathBuf}};
|
||||
|
||||
use crate::{Config, Error, ErrorInner, Partial, Source};
|
||||
use crate::{Config, Error, Partial, Source, error::ErrorInner};
|
||||
|
||||
|
||||
impl<C: Config> Source<C> for &Path {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//! intended to be used directly. None of this is covered by semver! Do not use
|
||||
//! any of this directly.
|
||||
|
||||
use crate::{Error, ErrorInner};
|
||||
use crate::{Error, error::ErrorInner};
|
||||
|
||||
pub fn deserialize_default<I, O>(src: I) -> Result<O, serde::de::value::Error>
|
||||
where
|
||||
|
||||
113
src/lib.rs
113
src/lib.rs
@@ -1,16 +1,19 @@
|
||||
use std::{ffi::OsString, fmt, path::PathBuf};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod internal;
|
||||
|
||||
mod error;
|
||||
mod file;
|
||||
|
||||
|
||||
pub use serde;
|
||||
pub use confique_macro::Config;
|
||||
pub use self::file::{File, FileFormat};
|
||||
pub use self::{
|
||||
error::Error,
|
||||
file::{File, FileFormat},
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// A configuration object that can be deserialized in layers via `serde`.
|
||||
@@ -83,107 +86,3 @@ pub trait Source<C: Config> {
|
||||
/// Attempts to load a potentially partially configuration object.
|
||||
fn load(&self) -> Result<C::Partial, Error>;
|
||||
}
|
||||
|
||||
/// Type describing all errors that can occur in this library.
|
||||
pub struct Error {
|
||||
inner: Box<ErrorInner>,
|
||||
}
|
||||
|
||||
enum ErrorInner {
|
||||
/// Returned by `Config::from_partial` when the partial does not contain
|
||||
/// values for all required configuration values. The string is a
|
||||
/// human-readable path to the value, e.g. `http.port`.
|
||||
MissingValue(String),
|
||||
|
||||
/// An IO error occured, e.g. when reading a file.
|
||||
Io {
|
||||
path: Option<PathBuf>,
|
||||
err: std::io::Error,
|
||||
},
|
||||
|
||||
/// Returned by `Source::load` implementations when deserialization fails.
|
||||
Deserialization {
|
||||
/// A human readable description for the error message, describing from
|
||||
/// what source it was attempted to deserialize. Completes the sentence
|
||||
/// "failed to deserialize configuration from ". E.g. "file 'foo.toml'"
|
||||
/// or "environment variable 'FOO_PORT'".
|
||||
source: Option<String>,
|
||||
err: Box<dyn std::error::Error + Send + Sync>,
|
||||
},
|
||||
|
||||
/// Returned by the [`Source`] impls for `Path` and `PathBuf` if the file
|
||||
/// extension is not supported by confique or if the corresponding Cargo
|
||||
/// feature of confique was not enabled.
|
||||
UnsupportedFileFormat {
|
||||
path: PathBuf,
|
||||
extension: OsString,
|
||||
},
|
||||
|
||||
/// Returned by the [`Source`] impls for `Path` and `PathBuf` if the path
|
||||
/// does not contain a file extension.
|
||||
MissingFileExtension {
|
||||
path: PathBuf,
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match &*self.inner {
|
||||
ErrorInner::Io { err, .. } => Some(err),
|
||||
ErrorInner::Deserialization { err, .. } => Some(&**err),
|
||||
ErrorInner::MissingValue(_)
|
||||
| ErrorInner::UnsupportedFileFormat { .. }
|
||||
| ErrorInner::MissingFileExtension { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match &*self.inner {
|
||||
ErrorInner::MissingValue(path) => {
|
||||
std::write!(f, "required configuration value is missing: '{}'", path)
|
||||
}
|
||||
ErrorInner::Io { path: Some(path), .. } => {
|
||||
std::write!(f,
|
||||
"IO error occured while reading configuration file '{}'",
|
||||
path.display(),
|
||||
)
|
||||
}
|
||||
ErrorInner::Io { path: None, .. } => {
|
||||
std::write!(f, "IO error occured while loading configuration")
|
||||
}
|
||||
ErrorInner::Deserialization { source: Some(source), .. } => {
|
||||
std::write!(f, "failed to deserialize configuration from {}", source)
|
||||
}
|
||||
ErrorInner::Deserialization { source: None, .. } => {
|
||||
std::write!(f, "failed to deserialize configuration")
|
||||
}
|
||||
ErrorInner::UnsupportedFileFormat { path, extension } => {
|
||||
std::write!(f,
|
||||
"unknown configuration file format '{}' of '{}'",
|
||||
extension.to_string_lossy(),
|
||||
path.display(),
|
||||
)
|
||||
}
|
||||
ErrorInner::MissingFileExtension { path } => {
|
||||
std::write!(f,
|
||||
"cannot guess configuration file format due to missing file extension in '{}'",
|
||||
path.display(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorInner> for Error {
|
||||
fn from(inner: ErrorInner) -> Self {
|
||||
Self { inner: Box::new(inner) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user