rta_for_fps_lib/
window.rs1use core::fmt::Debug;
4use core::marker::PhantomData;
5
6use crate::time::{TimeUnit, UnitNumber};
7use crate::window::window_types::WindowType;
8
9pub mod window_types {
10 use core::fmt::Debug;
13
14 use crate::seal::Seal;
15 use crate::window::{Demand, Overlap, Supply};
16
17 pub trait WindowType: Seal + Debug {}
19
20 impl WindowType for Supply {}
21
22 impl WindowType for Demand {}
23
24 impl<P: WindowType, Q: WindowType> WindowType for Overlap<P, Q> {}
25}
26
27mod window_end;
28
29pub use window_end::WindowEnd;
30
31#[derive(Debug, Hash, Eq)]
36pub struct Window<T> {
37 pub start: TimeUnit,
39 pub end: WindowEnd,
41 window_type: PhantomData<T>,
43}
44
45impl<W> PartialEq for Window<W> {
46 fn eq(&self, other: &Self) -> bool {
47 self.start == other.start && self.end == other.end
48 }
49}
50
51impl<T> Clone for Window<T> {
52 fn clone(&self) -> Self {
53 Window {
54 start: self.start,
55 end: self.end,
56 window_type: PhantomData,
57 }
58 }
59}
60
61impl<T> Window<T> {
62 #[must_use]
64 pub fn new<I: Into<TimeUnit>, E: Into<WindowEnd>>(start: I, end: E) -> Self {
65 Window {
66 start: start.into(),
67 end: end.into(),
68 window_type: PhantomData,
69 }
70 }
71
72 #[must_use]
74 pub const fn empty() -> Self {
75 Window {
76 start: TimeUnit::ZERO,
77 end: WindowEnd::Finite(TimeUnit::ZERO),
78 window_type: PhantomData,
79 }
80 }
81
82 #[must_use]
84 pub fn length(&self) -> WindowEnd {
85 match self.end {
86 WindowEnd::Finite(end) => {
87 let end = if self.start < end {
88 end - self.start
89 } else {
90 TimeUnit::ZERO
91 };
92 WindowEnd::Finite(end)
93 }
94 WindowEnd::Infinite => WindowEnd::Infinite,
95 }
96 }
97
98 #[must_use]
100 pub fn overlaps(&self, other: &Self) -> bool {
101 !(self.end < other.start || other.end < self.start)
102 }
103
104 #[must_use]
108 pub fn adjacent(&self, other: &Self) -> bool {
109 self.end == other.start || self.start == other.end
110 }
111
112 #[must_use]
114 pub fn delta<Q: WindowType>(supply: &Self, demand: &Window<Q>) -> WindowDeltaResult<T, Q>
115 where
116 T: WindowType,
117 {
118 if supply.end < demand.start {
119 WindowDeltaResult {
120 remaining_supply_head: supply.clone(),
121 remaining_supply_tail: Window::empty(),
122 overlap: Window::empty(),
123 remaining_demand: demand.clone(),
124 }
125 } else {
126 let overlap_start = TimeUnit::max(supply.start, demand.start);
127 let overlap_end: WindowEnd =
128 overlap_start + WindowEnd::min(demand.length(), supply.end - overlap_start);
129 let overlap = Window::new(overlap_start, overlap_end);
130
131 let remaining_demand = match overlap.length() {
132 WindowEnd::Finite(length) => Window::new(demand.start + length, demand.end),
133 WindowEnd::Infinite => {
134 Window::empty()
137 }
138 };
139
140 let remaining_supply_head = Window::new(supply.start, overlap.start);
141 let remaining_supply_tail = match overlap.end {
142 WindowEnd::Finite(overlap_end) => Window::new(overlap_end, supply.end),
143 WindowEnd::Infinite => {
144 Window::empty()
146 }
147 };
148
149 WindowDeltaResult {
150 remaining_supply_head,
151 remaining_supply_tail,
152 overlap,
153 remaining_demand,
154 }
155 }
156 }
157
158 #[must_use]
160 pub fn is_empty(&self) -> bool {
161 self.length() == TimeUnit::ZERO
162 }
163
164 #[must_use]
169 pub fn budget_group(&self, interval: TimeUnit) -> UnitNumber {
170 self.start / interval
171 }
172
173 #[must_use]
175 pub fn aggregate(&self, other: &Self) -> Option<Self> {
176 self.overlaps(other).then(|| {
178 let start = TimeUnit::min(self.start, other.start);
179 let end = start + self.length() + other.length();
180 Window::new(start, end)
181 })
182 }
183
184 pub fn reclassify<R>(self) -> Window<R> {
185 Window {
186 start: self.start,
187 end: self.end,
188 window_type: PhantomData,
189 }
190 }
191}
192
193#[derive(Debug, Eq, PartialEq)] pub struct WindowDeltaResult<P: WindowType, Q: WindowType> {
196 pub remaining_supply_head: Window<P>,
198 pub remaining_supply_tail: Window<P>,
200 pub overlap: Window<Overlap<P, Q>>,
202 pub remaining_demand: Window<Q>,
204}
205
206#[derive(Clone, Debug, Eq, PartialEq)]
208pub struct Supply;
209
210#[derive(Clone, Debug, Eq, PartialEq)]
212pub struct Demand;
213
214#[derive(Clone, Debug, Eq, PartialEq)]
216pub struct Overlap<P, Q>(PhantomData<(P, Q)>);