Skip to content

Commit

Permalink
Metric config creation may now return an error
Browse files Browse the repository at this point in the history
  • Loading branch information
rafal-ch committed Oct 14, 2024
1 parent f12185f commit a128622
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/metrics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ repository = { workspace = true }
description = "Fuel metrics"

[dependencies]
derive_more = { workspace = true }
once_cell = { workspace = true }
parking_lot = { workspace = true }
pin-project-lite = { workspace = true }
Expand Down
56 changes: 38 additions & 18 deletions crates/metrics/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ use strum_macros::{
EnumString,
};

#[derive(Debug, derive_more::Display)]
pub enum ConfigCreationError {
#[display(fmt = "Can not build config from empty value")]
EmptyValue,
#[display(fmt = "No such module: {}", _0)]
UnknownModule(String),
}

#[derive(Debug, Display, Clone, Copy, PartialEq, EnumString, EnumIter)]
#[strum(serialize_all = "lowercase")]
pub enum Module {
Expand All @@ -24,16 +32,27 @@ impl Config {
}
}

impl std::convert::From<&str> for Config {
fn from(s: &str) -> Self {
impl std::str::FromStr for Config {
// TODO: Figure out how to make `clap` work directly with `ConfigCreationError`
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "all" {
return Self(Module::iter().collect())
return Ok(Self(Module::iter().collect()))
}
if s.is_empty() {
return Err(ConfigCreationError::EmptyValue.to_string());
}

let mut modules = vec![];

for token in s.split(',') {
let parsed_module = token.parse::<Module>().map_err(|_| {
ConfigCreationError::UnknownModule(token.to_string()).to_string()
})?;
modules.push(parsed_module);
}
Self(
s.split(',')
.filter_map(|s| s.parse::<Module>().ok())
.collect(),
)

Ok(Self(modules))
}
}

Expand All @@ -51,6 +70,8 @@ pub fn help_string() -> &'static str {

#[cfg(test)]
mod tests {
use std::str::FromStr;

use strum::IntoEnumIterator;

use crate::config::{
Expand All @@ -77,28 +98,27 @@ mod tests {

let expected_disabled = [Module::Importer, Module::TxPool].to_vec();

let config: Config = EXCLUDED_METRICS.into();
let config = Config::from_str(EXCLUDED_METRICS).expect("should create config");
assert_config(&config, expected_disabled);
}

#[test]
fn metrics_config_with_incorrect_values() {
const EXCLUDED_METRICS: &str = "txpool,alpha,bravo";

let expected_disabled = [Module::TxPool].to_vec();

let config: Config = EXCLUDED_METRICS.into();
assert_config(&config, expected_disabled);
let config = Config::from_str(EXCLUDED_METRICS);
assert!(matches!(config, Err(err) if err == "No such module: alpha"));
}

#[test]
fn metrics_config_with_empty_value() {
// This case is still possible if someone calls `--disable-metrics ""`
const EXCLUDED_METRICS: &str = "";

let expected_disabled = vec![];

let config: Config = EXCLUDED_METRICS.into();
assert_config(&config, expected_disabled);
let config = Config::from_str(EXCLUDED_METRICS);
assert!(
matches!(config, Err(err) if err == "Can not build config from empty value")
);
}

#[test]
Expand All @@ -107,7 +127,7 @@ mod tests {

let expected_disabled = Module::iter().collect::<Vec<_>>();

let config: Config = EXCLUDED_METRICS.into();
let config = Config::from_str(EXCLUDED_METRICS).expect("should create config");
assert_config(&config, expected_disabled);
}
}

0 comments on commit a128622

Please sign in to comment.