From f5edc44717331633f2a0012cfda0fff038c1b164 Mon Sep 17 00:00:00 2001 From: mirsal Date: Thu, 15 May 2025 21:27:57 +0000 Subject: [PATCH] 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 --- src/config.rs | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/config.rs b/src/config.rs index 69862fd..a949b5f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -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 { + pub fn load(config_file: &str) -> Result { 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 for Error { + fn from(e: serde_yaml::Error) -> Self { + Self::InvalidFormatError(e) + } +} + +impl From 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 = std::result::Result;