use crate::patterns::observable::{Observable, Observer};
use crate::shared::SharedMut;
pub struct Settings<D> {
evaluation_date: Option<D>,
eval_date_observable: Observable,
include_reference_date_events: bool,
include_todays_cash_flows: Option<bool>,
enforces_todays_historic_fixings: bool,
}
impl<D> Default for Settings<D> {
fn default() -> Self {
Settings {
evaluation_date: None,
eval_date_observable: Observable::new(),
include_reference_date_events: false,
include_todays_cash_flows: None,
enforces_todays_historic_fixings: false,
}
}
}
impl<D> Settings<D> {
pub fn new() -> Self {
Settings::default()
}
pub fn evaluation_date(&self) -> Option<&D> {
self.evaluation_date.as_ref()
}
pub fn set_evaluation_date(&mut self, date: D)
where
D: PartialEq,
{
if self.evaluation_date.as_ref() != Some(&date) {
self.evaluation_date = Some(date);
self.eval_date_observable.notify_observers();
}
}
pub fn reset_evaluation_date(&mut self) {
if self.evaluation_date.is_some() {
self.evaluation_date = None;
self.eval_date_observable.notify_observers();
}
}
pub fn register_eval_date_observer(&self, observer: &SharedMut<dyn Observer>) -> bool {
self.eval_date_observable.register_observer(observer)
}
pub fn include_reference_date_events(&self) -> bool {
self.include_reference_date_events
}
pub fn set_include_reference_date_events(&mut self, value: bool) {
self.include_reference_date_events = value;
}
pub fn include_todays_cash_flows(&self) -> Option<bool> {
self.include_todays_cash_flows
}
pub fn set_include_todays_cash_flows(&mut self, value: Option<bool>) {
self.include_todays_cash_flows = value;
}
pub fn enforces_todays_historic_fixings(&self) -> bool {
self.enforces_todays_historic_fixings
}
pub fn set_enforces_todays_historic_fixings(&mut self, value: bool) {
self.enforces_todays_historic_fixings = value;
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::shared::{SharedMut, shared_mut};
#[derive(Default)]
struct Flag {
up: bool,
}
impl Observer for Flag {
fn update(&mut self) {
self.up = true;
}
}
#[test]
fn notifies_only_on_actual_date_change() {
let mut settings: Settings<i64> = Settings::new();
let d1 = 44238_i64; let d2 = 44239_i64;
settings.set_evaluation_date(d1);
let flag = shared_mut(Flag::default());
settings.register_eval_date_observer(&(flag.clone() as SharedMut<dyn Observer>));
settings.set_evaluation_date(d1);
assert!(!flag.borrow().up);
settings.set_evaluation_date(d2);
assert!(flag.borrow().up);
assert_eq!(settings.evaluation_date(), Some(&d2));
}
#[test]
fn reset_returns_to_floating_and_notifies_once() {
let mut settings: Settings<i64> = Settings::new();
settings.set_evaluation_date(44238_i64);
let flag = shared_mut(Flag::default());
settings.register_eval_date_observer(&(flag.clone() as SharedMut<dyn Observer>));
settings.reset_evaluation_date();
assert!(flag.borrow().up);
assert_eq!(settings.evaluation_date(), None);
flag.borrow_mut().up = false;
settings.reset_evaluation_date();
assert!(!flag.borrow().up);
}
#[test]
fn flags_round_trip() {
let mut settings: Settings<i64> = Settings::new();
assert!(!settings.include_reference_date_events());
assert_eq!(settings.include_todays_cash_flows(), None);
assert!(!settings.enforces_todays_historic_fixings());
settings.set_include_reference_date_events(true);
settings.set_include_todays_cash_flows(Some(true));
settings.set_enforces_todays_historic_fixings(true);
assert!(settings.include_reference_date_events());
assert_eq!(settings.include_todays_cash_flows(), Some(true));
assert!(settings.enforces_todays_historic_fixings());
}
}