rta_for_fps_lib/iterators/
task.rs

1//! Module for implementing `CurveIterator`s relate to Tasks
2
3use crate::curve::curve_types::CurveType;
4use crate::iterators::CurveIterator;
5use crate::task::curve_types::TaskDemand;
6use crate::task::Task;
7use crate::time::{TimeUnit, UnitNumber};
8use crate::window::{Demand, Window};
9
10/// `CurveIterator` for a Tasks Demand
11#[derive(Debug, Clone)]
12pub struct TaskDemandIterator {
13    /// the Task this Iterator generates demand for
14    task: Task,
15    /// The next Job index for which to generate Demand
16    next_job: UnitNumber,
17}
18
19impl TaskDemandIterator {
20    /// Create a `CurveIterator` for a Tasks Demand
21    #[must_use]
22    pub const fn new(task: Task) -> Self {
23        TaskDemandIterator { task, next_job: 0 }
24    }
25}
26
27impl CurveIterator for TaskDemandIterator {
28    type CurveKind = TaskDemand;
29
30    fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
31        // using checked arithmetic to stop on overflow
32        let start = self
33            .task
34            .offset
35            .as_unit()
36            .checked_add(self.next_job.checked_mul(self.task.interval.as_unit())?)?;
37        let end = UnitNumber::checked_add(start, self.task.demand.as_unit())?;
38        self.next_job = self.next_job.checked_add(1)?;
39        Some(Window::new(TimeUnit::from(start), TimeUnit::from(end)))
40    }
41}
42
43impl Iterator for TaskDemandIterator {
44    type Item = Window<Demand>;
45
46    fn next(&mut self) -> Option<Self::Item> {
47        self.next_window()
48    }
49}