use crate::construction::enablers::ScheduleKeys;
use crate::construction::features::CapacityKeys;
use crate::construction::heuristics::StateKeyRegistry;
use crate::models::common::{Dimensions, ValueDimension};
use crate::solver::HeuristicKeys;
use rosomaxa::prelude::GenericError;
use std::sync::Arc;
pub struct Extras {
index: Dimensions,
}
impl Extras {
pub fn get_value_raw<T: 'static + Send + Sync>(&self, key: &str) -> Option<Arc<T>> {
self.index.get(key).cloned().and_then(|any| any.downcast::<T>().ok())
}
}
pub struct ExtrasBuilder(Extras);
impl Default for ExtrasBuilder {
fn default() -> Self {
Self::new(&mut StateKeyRegistry::default())
}
}
impl From<&Extras> for ExtrasBuilder {
fn from(extras: &Extras) -> Self {
Self(Extras { index: extras.index.clone() })
}
}
impl ExtrasBuilder {
pub fn new(state_registry: &mut StateKeyRegistry) -> Self {
let mut builder = Self(Extras { index: Default::default() });
builder
.with_schedule_keys(ScheduleKeys::from(&mut *state_registry))
.with_capacity_keys(CapacityKeys::from(&mut *state_registry))
.with_heuristic_keys(HeuristicKeys::from(&mut *state_registry));
builder
}
pub fn with_schedule_keys(&mut self, schedule_keys: ScheduleKeys) -> &mut Self {
self.0.set_value("schedule_keys", schedule_keys);
self
}
pub fn with_capacity_keys(&mut self, capacity_keys: CapacityKeys) -> &mut Self {
self.0.set_value("capacity_keys", capacity_keys);
self
}
pub fn with_heuristic_keys(&mut self, heuristic_keys: HeuristicKeys) -> &mut Self {
self.0.set_value("heuristic_keys", heuristic_keys);
self
}
pub fn with_custom_key<T: 'static + Sync + Send>(&mut self, key: &str, value: Arc<T>) -> &mut Self {
self.0.index.insert(key.to_string(), value);
self
}
pub fn build(&mut self) -> Result<Extras, GenericError> {
let error =
[("schedule_keys", "schedule keys needs to be set"), ("heuristic_keys", "heuristic keys needs to be set")]
.iter()
.filter(|(key, _)| !self.0.index.contains_key(*key))
.map(|(_, msg)| GenericError::from(*msg))
.next();
if let Some(error) = error {
return Err(error);
}
Ok(Extras { index: std::mem::take(&mut self.0.index) })
}
}
pub trait CoreStateKeys {
fn get_schedule_keys(&self) -> Option<&ScheduleKeys>;
fn get_capacity_keys(&self) -> Option<&CapacityKeys>;
fn get_heuristic_keys(&self) -> Option<&HeuristicKeys>;
}
impl CoreStateKeys for Extras {
fn get_schedule_keys(&self) -> Option<&ScheduleKeys> {
self.get_value("schedule_keys")
}
fn get_capacity_keys(&self) -> Option<&CapacityKeys> {
self.get_value("capacity_keys")
}
fn get_heuristic_keys(&self) -> Option<&HeuristicKeys> {
self.get_value("heuristic_keys")
}
}
impl ValueDimension for Extras {
fn get_value<T: 'static>(&self, key: &str) -> Option<&T> {
self.index.get_value(key)
}
fn set_value<T: 'static + Sync + Send>(&mut self, key: &str, value: T) {
self.index.set_value(key, value)
}
}