use crate::calendar::{Calendar, Holiday, NthWeek};
use chrono::{Weekday, NaiveDate};
use std::collections::HashMap;
use std::fmt;
use std::error::Error;
#[derive(Debug)]
pub enum MarketError {
CalendarNotFound
}
impl fmt::Display for MarketError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "unknown calendar")
}
}
impl Error for MarketError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
pub struct Market{
calendars: HashMap<String, Calendar>,
}
impl Market {
pub fn new() -> Market {
Market{ calendars: generate_calendars() }
}
pub fn get_calendar(&self, name: &str) -> Result<&Calendar,MarketError> {
if self.calendars.contains_key(name) {
Ok(&self.calendars[name])
} else {
Err(MarketError::CalendarNotFound)
}
}
}
fn generate_calendars() -> HashMap<String, Calendar> {
let mut calendars = HashMap::new();
let uk_settlement_holidays = vec![
Holiday::WeekDay(Weekday::Sat),
Holiday::WeekDay(Weekday::Sun),
Holiday::MovableYearlyDay{month: 1, day: 1, first: None, last: None},
Holiday::EasterOffset{offset: -2, first: None, last: None},
Holiday::EasterOffset{offset: 1, first: None, last: None},
Holiday::MonthWeekday{month: 5, weekday: Weekday::Mon, nth: NthWeek::First, first: None, last: Some(1994) },
Holiday::SingularDay(NaiveDate::from_ymd(1995,5,8)),
Holiday::MonthWeekday{month: 5, weekday: Weekday::Mon, nth: NthWeek::First, first: Some(1996), last: Some(2019) },
Holiday::SingularDay(NaiveDate::from_ymd(2020,5,8)),
Holiday::MonthWeekday{month: 5, weekday: Weekday::Mon, nth: NthWeek::First, first: Some(2021), last: None },
Holiday::MonthWeekday{month: 5, weekday: Weekday::Mon, nth: NthWeek::Last, first: None, last: Some(2001) },
Holiday::MonthWeekday{month: 5, weekday: Weekday::Mon, nth: NthWeek::Last, first: Some(2003), last: Some(2011)},
Holiday::MonthWeekday{month: 5, weekday: Weekday::Mon, nth: NthWeek::Last, first: Some(2013), last: None },
Holiday::MonthWeekday{month: 8, weekday: Weekday::Mon, nth: NthWeek::Last, first: None, last: None },
Holiday::MovableYearlyDay{month: 12, day: 25, first: None, last: None},
Holiday::MovableYearlyDay{month: 12, day: 26, first: None, last: None},
Holiday::SingularDay(NaiveDate::from_ymd(2002,6,3)),
Holiday::SingularDay(NaiveDate::from_ymd(2002,6,4)),
Holiday::SingularDay(NaiveDate::from_ymd(2011,4,29)),
Holiday::SingularDay(NaiveDate::from_ymd(2012,6,4)),
Holiday::SingularDay(NaiveDate::from_ymd(2012,6,5)),
Holiday::SingularDay(NaiveDate::from_ymd(1999,12,31)),
];
let uk_cal = Calendar::calc_calendar(&uk_settlement_holidays, 1990, 2050);
calendars.insert("uk".to_string(), uk_cal);
let target_holidays = vec![
Holiday::WeekDay(Weekday::Sat),
Holiday::WeekDay(Weekday::Sun),
Holiday::YearlyDay{month: 1, day: 1, first: None, last: None},
Holiday::EasterOffset{offset: -2, first: Some(2000), last: None},
Holiday::EasterOffset{offset: 1, first: Some(2000), last: None},
Holiday::YearlyDay{month: 5, day: 1, first: Some(2000), last: None},
Holiday::YearlyDay{month: 5, day: 1, first: Some(2000), last: None},
Holiday::YearlyDay{month: 5, day: 1, first: Some(2000), last: None},
Holiday::SingularDay(NaiveDate::from_ymd(1995,5,8)),
];
let target_cal = Calendar::calc_calendar(&target_holidays, 1990, 2050);
calendars.insert("TARGET".to_string(), target_cal);
calendars
}