use sim_kernel::{Error, Ref, Result, Symbol, Tick};
pub const CLOCK_INDEX_REF_NAMESPACE: &str = "stream/clock-index";
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ClockTickIndex(u64);
impl ClockTickIndex {
pub fn new(value: u64) -> Self {
Self(value)
}
pub fn value(self) -> u64 {
self.0
}
}
pub fn clock_index_ref(index: u64) -> Ref {
Ref::Symbol(clock_index_symbol(index))
}
pub fn clock_index_symbol(index: u64) -> Symbol {
Symbol::qualified(CLOCK_INDEX_REF_NAMESPACE, index.to_string())
}
pub fn tick_clock_index(tick: &Tick, expected_clock: &Symbol) -> Result<Option<ClockTickIndex>> {
if &tick.clock != expected_clock {
return Ok(None);
}
let Ref::Symbol(symbol) = &tick.index else {
return Err(incomparable_tick_error(tick));
};
if symbol.namespace.as_deref() != Some(CLOCK_INDEX_REF_NAMESPACE) {
return Err(incomparable_tick_error(tick));
}
let index = symbol.name.parse::<u64>().map_err(|err| {
Error::Eval(format!(
"stream tick on clock {} has invalid semantic index {}: {err}",
tick.clock.as_qualified_str(),
symbol.name
))
})?;
Ok(Some(ClockTickIndex::new(index)))
}
fn incomparable_tick_error(tick: &Tick) -> Error {
Error::Eval(format!(
"stream tick on clock {} has incomparable index {:?}; expected {CLOCK_INDEX_REF_NAMESPACE}/<u64>",
tick.clock.as_qualified_str(),
tick.index
))
}