config: Make error handling a little bit nicer

* Implement the std::error::Error trait and add a Result type
 * Propagate generic io::Error and serde_yaml::Error using From
 * Move the Result and Error types to the bottom of the module
This commit is contained in:
2025-05-15 21:27:57 +00:00
parent 73ee8114ca
commit f5edc44717

View File

@ -18,16 +18,7 @@
*/
use serde::Deserialize;
use std::{fs, io};
#[derive(Debug)]
#[allow(dead_code)]
pub enum Error {
FileNotFoundError(String),
PermissionDeniedError(),
InvalidFormatError(serde_yaml::Error),
IoError(io::Error),
}
use std::{fs, io, fmt};
#[derive(Deserialize, Clone, Debug)]
pub struct FeedConfig {
@ -46,19 +37,49 @@ pub struct Config {
}
impl Config {
pub fn load(config_file: &str) -> Result<Self, Error> {
pub fn load(config_file: &str) -> Result<Self> {
let serialized_config = fs::read_to_string(config_file).map_err(|e| {
match e.kind() {
io::ErrorKind::NotFound => Error::FileNotFoundError(config_file.into()),
io::ErrorKind::PermissionDenied => Error::PermissionDeniedError(),
_ => Error::IoError(e),
_ => e.into(),
}
})?;
let config: Config = serde_yaml::from_str(&serialized_config)
.map_err(|e| Error::InvalidFormatError(e))?;
let config: Config = serde_yaml::from_str(&serialized_config)?;
Ok(config)
}
}
#[derive(Debug)]
#[allow(dead_code)] // we use Debug, so inner fields are never read
pub enum Error {
FileNotFoundError(String),
PermissionDeniedError(),
InvalidFormatError(serde_yaml::Error),
IoError(io::Error),
}
impl From<serde_yaml::Error> for Error {
fn from(e: serde_yaml::Error) -> Self {
Self::InvalidFormatError(e)
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Self::IoError(e)
}
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
write!(fmt, "{self:?}")
}
}
pub type Result<T> = std::result::Result<T, Error>;