use core::convert::Infallible;
use core::fmt;
use core::future::Future;
use proxima_primitives::pipe::primitives::Pipe;
use crate::seq_u64s::SeqU64s;
use crate::ticks::Ticks;
pub struct TickCell {
ticks: SeqU64s<1>,
}
impl TickCell {
#[must_use]
pub fn new(initial: Ticks) -> Self {
Self {
ticks: SeqU64s::new([initial.as_raw()]),
}
}
pub fn set(&self, ticks: Ticks) {
self.ticks.store([ticks.as_raw()]);
}
#[must_use]
pub fn get(&self) -> Ticks {
let [raw] = self.ticks.load();
Ticks::from_raw(raw)
}
}
impl fmt::Debug for TickCell {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("TickCell")
.field("ticks", &self.get())
.finish()
}
}
impl Pipe for &TickCell {
type In = ();
type Out = Ticks;
type Err = Infallible;
fn call(&self, (): ()) -> impl Future<Output = Result<Ticks, Infallible>> {
let ticks = self.get();
async move { Ok(ticks) }
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::TickCell;
use crate::ticks::Ticks;
use proxima_primitives::block_on;
use proxima_primitives::pipe::primitives::Pipe;
#[test]
fn set_then_get_round_trips() {
let cell = TickCell::new(Ticks::from_raw(1_000));
cell.set(Ticks::from_raw(2_000));
assert_eq!(cell.get(), Ticks::from_raw(2_000));
}
#[test]
fn reads_as_a_source_pipe() {
let cell = TickCell::new(Ticks::from_raw(24_000_000));
let read = block_on(Pipe::call(&&cell, ())).expect("cell reads never fail");
assert_eq!(read, Ticks::from_raw(24_000_000));
}
#[cfg(feature = "std")]
mod rendering {
use super::TickCell;
use crate::ticks::Ticks;
#[test]
fn debug_renders_the_live_value_not_the_constructed_one() {
let cell = TickCell::new(Ticks::from_raw(1_000));
cell.set(Ticks::from_raw(2_000));
assert_eq!(format!("{cell:?}"), "TickCell { ticks: Ticks(2000) }");
}
}
}