diff --git a/Cargo.toml b/Cargo.toml index 40cc5dd..48ed730 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ name = "init4-bin-base" description = "Internal utilities for binaries produced by the init4 team" keywords = ["init4", "bin", "base"] -version = "0.9.1" +version = "0.9.2" edition = "2021" rust-version = "1.81" authors = ["init4", "James Prestwich"] diff --git a/src/utils/from_env.rs b/src/utils/from_env.rs index df26f79..c455266 100644 --- a/src/utils/from_env.rs +++ b/src/utils/from_env.rs @@ -3,6 +3,7 @@ use signet_constants::{ SignetSystemConstants, }; use std::{convert::Infallible, env::VarError, num::ParseIntError, str::FromStr}; +use tracing_core::metadata::ParseLevelError; /// The `derive(FromEnv)` macro. /// @@ -278,7 +279,7 @@ pub fn parse_env_if_present(env_var: &str) -> Result Result>; @@ -613,7 +614,6 @@ impl_for_parseable!( i128, isize, url::Url, - tracing::Level, SignetConstants, SignetEnvironmentConstants, SignetSystemConstants, @@ -646,6 +646,28 @@ impl FromEnvVar for bool { } } +/// Error type for parsing tracing levels from the environment. +#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)] +#[error("failed to parse tracing level from environment variable")] +pub struct LevelParseError; + +impl From for LevelParseError { + fn from(_: ParseLevelError) -> Self { + LevelParseError + } +} + +impl FromEnvVar for tracing::Level { + type Error = LevelParseError; + + fn from_env_var(env_var: &str) -> Result> { + let s: String = std::env::var(env_var).map_err(|e| FromEnvErr::env_err(env_var, e))?; + s.parse() + .map_err(Into::into) + .map_err(FromEnvErr::parse_error) + } +} + #[cfg(test)] mod test { use std::{borrow::Cow, time::Duration}; diff --git a/src/utils/provider.rs b/src/utils/provider.rs index eafddaf..cacef08 100644 --- a/src/utils/provider.rs +++ b/src/utils/provider.rs @@ -8,12 +8,43 @@ use alloy::{ }, }; +/// Errors when connecting a provider +#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)] +pub enum ProviderConnectError { + /// Pubsub is not available for the configured transport + #[error("pubsub is not available for the configured transport")] + PubsubUnavailable, + /// Custom error message + #[error("{0}")] + Custom(String), +} + +impl From for ProviderConnectError { + fn from(err: TransportErrorKind) -> Self { + match err { + TransportErrorKind::Custom(err) => ProviderConnectError::Custom(err.to_string()), + TransportErrorKind::PubsubUnavailable => ProviderConnectError::PubsubUnavailable, + _ => panic!("Unexpected TransportErrorKind variant: {err:?}"), + } + } +} + +impl From for ProviderConnectError { + fn from(err: TransportError) -> Self { + match err { + TransportError::Transport(e) => e.into(), + _ => panic!("Unexpected TransportError variant: {err:?}"), + } + } +} + impl FromEnvVar for BuiltInConnectionString { - type Error = TransportError; + type Error = ProviderConnectError; fn from_env_var(env_var: &str) -> Result> { let conn_str = String::from_env_var(env_var).map_err(FromEnvErr::infallible_into)?; - conn_str.parse().map_err(Into::into) + let built_in = conn_str.parse().map_err(ProviderConnectError::from)?; + Ok(built_in) } } @@ -41,7 +72,7 @@ impl ProviderConfig { } impl FromEnvVar for ProviderConfig { - type Error = TransportError; + type Error = ProviderConnectError; fn from_env_var(env_var: &str) -> Result> { let connection_string = BuiltInConnectionString::from_env_var(env_var)?; @@ -81,21 +112,21 @@ impl PubSubConfig { } impl TryFrom for PubSubConfig { - type Error = TransportError; + type Error = ProviderConnectError; fn try_from(connection_string: BuiltInConnectionString) -> Result { if !matches!( connection_string, BuiltInConnectionString::Ws(_, _) | BuiltInConnectionString::Ipc(_) ) { - return Err(TransportErrorKind::pubsub_unavailable()); + return Err(ProviderConnectError::PubsubUnavailable); } Ok(Self { connection_string }) } } impl FromEnvVar for PubSubConfig { - type Error = TransportError; + type Error = ProviderConnectError; fn from_env_var(env_var: &str) -> Result> { let cs = BuiltInConnectionString::from_env_var(env_var)?; @@ -137,3 +168,18 @@ impl PubSubConnect for PubSubConfig { } } } + +#[cfg(test)] +mod test { + use super::*; + use crate::utils::from_env::FromEnv; + + #[derive(FromEnv, Debug, Clone, PartialEq, Eq)] + #[from_env(crate)] + struct CompileCheck { + #[from_env(var = "COOL_DUDE", desc = "provider")] + cool_dude: ProviderConfig, + #[from_env(var = "COOL_DUDE2", desc = "provider2")] + cool_dude2: PubSubConfig, + } +}