1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
//! This module contains types related to handling and processing metric commands during railway simulations.
//!
//! `MetricsCommand` is an enumeration of subcommands for working with metrics in the simulation.
//! It provides the `List` and `Get` subcommands to list available metrics and get a specific metric's value.
//!
//! This module integrates with the `Simulation` struct and the `MetricsHandler` trait to process and display metric information.
use crate::simulation::commands::SimulationCommand;
use crate::simulation::metrics::{ActionCountHandler, MetricsHandler, TargetReachedHandler};
use crate::simulation::Simulation;
use clap::Parser;
/// An enumeration of subcommands for working with metrics in the simulation.
#[derive(Parser, Debug)]
#[command(name = "metrics")]
pub enum MetricsCommand {
/// Lists the names of all available metrics.
#[command(name = "list")]
List,
/// Retrieves the value of a specific metric.
#[command(name = "get")]
Get(GetMetric),
}
/// A struct representing the `Get` subcommand for retrieving a specific metric's value.
#[derive(Parser, Debug)]
#[command(name = "get")]
pub struct GetMetric {
/// The identifier of the metric to retrieve.
#[clap(name = "ID")]
pub metric_id: String,
}
/// Implements the `SimulationCommand` trait for the `MetricsCommand` enumeration.
impl SimulationCommand for MetricsCommand {
/// Executes the metric command, either listing available metrics or getting a specific metric's value.
///
/// # Returns
///
/// An optional `String` containing the command's output.
fn execute(&self, simulation: &mut Simulation) -> Option<String> {
match self {
MetricsCommand::List => {
let metric_names = vec!["ActionCount", "TargetReached"];
Some(format!("Available metrics: {:?}", metric_names))
}
MetricsCommand::Get(get_metric) => {
let metric_value = match get_metric.metric_id.as_str() {
"ActionCount" => {
let handler = simulation.metrics_handlers.iter().find_map(|handler| {
handler.as_any().downcast_ref::<ActionCountHandler>()
});
handler.map(|h| h.get_value())
}
"TargetReached" => {
let handler = simulation.metrics_handlers.iter().find_map(|handler| {
handler.as_any().downcast_ref::<TargetReachedHandler>()
});
handler.map(|h| h.get_value())
}
_ => None,
};
if let Some(value) = metric_value {
Some(format!("{}: {}", get_metric.metric_id, value))
} else {
Some(format!("Metric '{}' not found", get_metric.metric_id))
}
}
}
}
}