///|
/// Create an inclusive forward date series.
pub fn DateSeries::new(
start~ : Date,
end~ : Date,
step~ : Int,
) -> Result[DateSeries, SeriesError] {
if step <= 0 {
Err(SeriesInvalidStep)
} else if start > end {
Err(SeriesReversed)
} else {
Ok({ start, end, step })
}
}
///|
/// Materialize the inclusive date series.
pub fn DateSeries::collect(
self : DateSeries,
) -> Result[Array[Date], SeriesError] {
let dates = Array::new()
let mut current = self.start
while current <= self.end {
dates.push(current)
if current == self.end {
break
}
current = match current.try_add_days(self.step) {
Ok(value) => value
Err(_) => return Err(SeriesOutOfRange)
}
}
Ok(dates)
}
///|
/// Check whether a date lies on a generated series point.
pub fn DateSeries::contains(self : DateSeries, date : Date) -> Bool {
if date < self.start || date > self.end {
false
} else {
(date.ordinal() - self.start.ordinal()) % self.step == 0
}
}
///|
/// Create a materialized business-day series over a closed interval.
pub fn BusinessDaySeries::new(
calendar~ : Calendar,
start~ : Date,
end~ : Date,
) -> Result[BusinessDaySeries, SeriesError] {
if start > end {
Err(SeriesReversed)
} else {
Ok({ calendar, start, end })
}
}
///|
/// Collect only business dates in the interval.
pub fn BusinessDaySeries::collect(self : BusinessDaySeries) -> Array[Date] {
let dates = Array::new()
let mut current = self.start
while true {
if self.calendar.is_business_day(current) {
dates.push(current)
}
if current == self.end {
break
}
current = match current.try_add_days(1) {
Ok(value) => value
Err(_) => break
}
}
dates
}