use serde::{Deserialize, Serialize};
use super::super::names::MetricName;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum MetricDirection {
Maximize,
Minimize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum MetricVisibility {
Public,
Official,
}
#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
pub struct MetricDefinitionSpec {
pub name: MetricName,
pub label: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub unit: Option<String>,
pub direction: MetricDirection,
pub visibility: MetricVisibility,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub metric_description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
pub struct RankingSpec {
pub primary_metric_name: MetricName,
#[serde(default)]
#[schemars(required)]
pub tie_breaker_metric_names: Vec<MetricName>,
}
#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
pub struct MetricSchemaSpec {
pub metrics: Vec<MetricDefinitionSpec>,
pub ranking: RankingSpec,
}
impl MetricSchemaSpec {
pub fn metric(&self, metric_name: &MetricName) -> Option<&MetricDefinitionSpec> {
self.metrics
.iter()
.find(|metric| &metric.name == metric_name)
}
pub fn primary_metric(&self) -> Option<&MetricDefinitionSpec> {
self.metric(&self.ranking.primary_metric_name)
}
}
impl Default for MetricSchemaSpec {
fn default() -> Self {
Self {
metrics: vec![MetricDefinitionSpec {
name: MetricName::score(),
label: "Score".to_string(),
unit: None,
direction: MetricDirection::Maximize,
visibility: MetricVisibility::Public,
metric_description: Some("Challenge-defined compatibility score.".to_string()),
}],
ranking: RankingSpec {
primary_metric_name: MetricName::score(),
tie_breaker_metric_names: vec![],
},
}
}
}