sva_engine/offset.rs
1// Concern: where a ref reads its source, and the index it names at a rate | Non-concern: the reading node's type (typing.rs) | IO: (Offset, rate) -> an index or the count needed
2
3/// A duration is an index offset only once an observation names a rate.
4#[derive(Clone, Copy, Debug, PartialEq)]
5pub enum Offset {
6 Steps(i64),
7 Secs(f64),
8}
9
10/// A duration carries the rounding of its own decimal, so a sample count is whole to
11/// floating precision rather than exactly.
12const GRID_EPSILON: f64 = 1e-9;
13
14impl Offset {
15 pub fn steps_at(self, rate: u32) -> Result<i64, f64> {
16 match self {
17 Offset::Steps(steps) => Ok(steps),
18 Offset::Secs(secs) => {
19 let count = secs * f64::from(rate);
20 let whole = count.round();
21 match (count - whole).abs() <= GRID_EPSILON * count.abs().max(1.0) {
22 true => Ok(whole as i64),
23 false => Err(count),
24 }
25 }
26 }
27 }
28}