use crate::*;
pub mod control;
pub mod converters;
pub mod flow;
pub mod logic;
pub mod math;
pub struct Latest<const C: usize, G> {
inputs: [G; C],
}
impl<const C: usize, G> Latest<C, G> {
#[inline]
pub const fn new(inputs: [G; C]) -> Self {
Self { inputs }
}
}
impl<T, const C: usize, G: Getter<T, E>, E: Clone + Debug> Getter<T, E> for Latest<C, G> {
fn get(&self) -> Output<T, E> {
let mut output: Option<Datum<T>> = None;
for getter in &self.inputs {
let gotten = getter.get()?;
if let Some(gotten) = gotten {
match &output {
Some(thing) => {
if gotten.time > thing.time {
output = Some(gotten);
}
}
None => {
output = Some(gotten);
}
}
}
}
Ok(output)
}
}
impl<const C: usize, G: Updatable<E>, E: Clone + Debug> Updatable<E> for Latest<C, G> {
fn update(&mut self) -> NothingOrError<E> {
for getter in &mut self.inputs {
getter.update()?;
}
Ok(())
}
}
pub struct Latest2<G1, G2> {
input1: G1,
input2: G2,
}
impl<G1, G2> Latest2<G1, G2> {
#[inline]
pub const fn new(input1: G1, input2: G2) -> Self {
Self { input1, input2 }
}
}
impl<G1: Updatable<E>, G2: Updatable<E>, E: Clone + Debug> Updatable<E> for Latest2<G1, G2> {
fn update(&mut self) -> NothingOrError<E> {
self.input1.update()?;
self.input2.update()
}
}
impl<T, G1: Getter<T, E>, G2: Getter<T, E>, E: Clone + Debug> Getter<T, E> for Latest2<G1, G2> {
fn get(&self) -> Output<T, E> {
let gotten_from_1 = match self.input1.get() {
Err(error) => return Err(error),
Ok(None) => return self.input2.get(),
Ok(Some(datum)) => datum,
};
match self.input2.get() {
Err(error) => Err(error),
Ok(None) => Ok(Some(gotten_from_1)),
Ok(Some(gotten_from_2)) => Ok(Some(latest(gotten_from_1, gotten_from_2))),
}
}
}
pub struct Expirer<G, TG> {
input: G,
time_getter: TG,
max_time_delta: Time,
}
impl<G, TG> Expirer<G, TG> {
pub const fn new(input: G, time_getter: TG, max_time_delta: Time) -> Self {
Self {
input,
time_getter,
max_time_delta,
}
}
}
impl<T, G, TG, E> Getter<T, E> for Expirer<G, TG>
where
G: Getter<T, E>,
TG: TimeGetter<E>,
E: Clone + Debug,
{
fn get(&self) -> Output<T, E> {
let output = match self.input.get()? {
Some(datum) => datum,
None => return Ok(None),
};
let time = self.time_getter.get()?;
if time - output.time > self.max_time_delta {
return Ok(None);
}
Ok(Some(output))
}
}
impl<G, TG, E> Updatable<E> for Expirer<G, TG>
where
G: Updatable<E>,
TG: Updatable<E>,
E: Clone + Debug,
{
fn update(&mut self) -> NothingOrError<E> {
self.time_getter.update()?;
self.input.update()?;
Ok(())
}
}
#[cfg(feature = "std")]
pub struct DebugStream<G> {
input: G,
silent: bool,
name: Option<String>,
}
#[cfg(feature = "std")]
impl<G> DebugStream<G> {
#[inline]
pub const fn new(input: G) -> Self {
Self {
input,
silent: false,
name: None,
}
}
#[inline]
pub const fn with_name(input: G, name: String) -> Self {
Self {
input,
silent: false,
name: Some(name),
}
}
#[inline]
pub const fn set_silent(&mut self, silent: bool) {
self.silent = silent;
}
#[inline]
pub fn change_name(&mut self, name: Option<String>) {
self.name = name;
}
fn to_prepend(&self) -> String {
if let Some(name) = &self.name {
format!("{}: ", name)
} else {
String::new()
}
}
}
#[cfg(feature = "std")]
impl<G: Updatable<E>, E: Clone + Debug> Updatable<E> for DebugStream<G> {
fn update(&mut self) -> NothingOrError<E> {
if self.silent {
self.input.update()
} else {
let update = self.input.update();
eprintln!("{}rrtk::Updatable::update: {:?}", self.to_prepend(), update);
update
}
}
}
#[cfg(feature = "std")]
impl<T: Debug, G: Getter<T, E>, E: Clone + Debug> Getter<T, E> for DebugStream<G> {
fn get(&self) -> Output<T, E> {
if self.silent {
self.input.get()
} else {
let get = self.input.get();
eprintln!("{}rrtk::Getter::get: {:?}", self.to_prepend(), get);
get
}
}
}
#[cfg(feature = "std")]
impl<T: Debug, G: Settable<T, E>, E: Clone + Debug> Settable<T, E> for DebugStream<G> {
fn set(&mut self, value: T) -> NothingOrError<E> {
if self.silent {
self.input.set(value)
} else {
let value_string = format!("{:?}", value);
let set = self.input.set(value);
eprintln!(
r#"{}rrtk::Settable::set: setting to "{}" returned "{:?}""#,
self.to_prepend(),
value_string,
set
);
set
}
}
}
#[cfg(feature = "std")]
impl<G: TimeGetter<E>, E: Clone + Debug> TimeGetter<E> for DebugStream<G> {
fn get(&self) -> TimeOutput<E> {
if self.silent {
self.input.get()
} else {
let get = self.input.get();
eprintln!("{}rrtk::TimeGetter::get: {:?}", self.to_prepend(), get);
get
}
}
}
#[cfg(feature = "std")]
impl<T: Debug, G: Chronology<T>> Chronology<T> for DebugStream<G> {
fn get(&self, time: Time) -> Option<Datum<T>> {
if self.silent {
self.input.get(time)
} else {
let get = self.input.get(time);
eprintln!("{}rrtk::Chronology::get: {:?}", self.to_prepend(), get);
get
}
}
}
#[cfg(all(feature = "std", feature = "devices"))]
impl<G: devices::DeviceUpdatable<E>, E: Debug> devices::DeviceUpdatable<E> for DebugStream<G> {
fn device_update<const N: usize>(
&mut self,
system: &mut devices::System<N>,
) -> NothingOrError<E> {
if self.silent {
self.input.device_update(system)
} else {
let device_update = self.input.device_update(system);
eprintln!(
"{}rrtk::devices::DeviceUpdatable::device_update: {:?}",
self.to_prepend(),
device_update
);
device_update
}
}
}