use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "snake_case", tag = "term")]
#[non_exhaustive]
pub enum ObjectiveTerm {
NetworkGeneratorCost,
NetworkPerPhaseCost,
DifferentiabilityRegularization { weight: f64 },
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct Objective {
terms: Vec<ObjectiveTerm>,
}
impl Objective {
#[must_use]
pub const fn none() -> Self {
Self { terms: Vec::new() }
}
#[must_use]
pub fn network_generator_cost() -> Self {
Self {
terms: vec![ObjectiveTerm::NetworkGeneratorCost],
}
}
#[must_use]
pub fn network_per_phase_cost() -> Self {
Self {
terms: vec![ObjectiveTerm::NetworkPerPhaseCost],
}
}
#[must_use]
pub fn with_term(mut self, term: ObjectiveTerm) -> Self {
self.terms.push(term);
self
}
#[must_use]
pub fn terms(&self) -> &[ObjectiveTerm] {
&self.terms
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_objective_states_its_terms_in_order() {
let objective = Objective::network_generator_cost()
.with_term(ObjectiveTerm::DifferentiabilityRegularization { weight: 1e-6 });
assert_eq!(objective.terms().len(), 2);
assert_eq!(objective.terms()[0], ObjectiveTerm::NetworkGeneratorCost);
let wire = serde_json::to_value(&objective).unwrap();
assert_eq!(wire["terms"][1]["term"], "differentiability_regularization");
assert_eq!(wire["terms"][1]["weight"], 1e-6);
}
}