Skip to main content

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}