use crate::*;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Datum<T> {
pub time: Time,
pub value: T,
}
impl<T> Datum<T> {
pub const fn new(time: Time, value: T) -> Datum<T> {
Datum { time, value }
}
pub fn replace_if_older_than(&mut self, maybe_replace_with: Self) -> bool {
if maybe_replace_with.time > self.time {
*self = maybe_replace_with;
return true;
}
false
}
}
pub trait OptionDatumExt<T> {
fn replace_if_none_or_older_than(&mut self, maybe_replace_with: Datum<T>) -> bool;
fn replace_if_none_or_older_than_option(&mut self, maybe_replace_with: Self) -> bool;
}
impl<T> OptionDatumExt<T> for Option<Datum<T>> {
fn replace_if_none_or_older_than(&mut self, maybe_replace_with: Datum<T>) -> bool {
if let Some(self_datum) = self {
if self_datum.time >= maybe_replace_with.time {
return false;
}
}
*self = Some(maybe_replace_with);
true
}
fn replace_if_none_or_older_than_option(&mut self, maybe_replace_with: Self) -> bool {
let maybe_replace_with = match maybe_replace_with {
Some(x) => x,
None => return false,
};
self.replace_if_none_or_older_than(maybe_replace_with)
}
}
pub trait NotDatum {}
impl NotDatum for u8 {}
impl NotDatum for u16 {}
impl NotDatum for u32 {}
impl NotDatum for u64 {}
impl NotDatum for u128 {}
impl NotDatum for usize {}
impl NotDatum for i8 {}
impl NotDatum for i16 {}
impl NotDatum for i32 {}
impl NotDatum for i64 {}
impl NotDatum for i128 {}
impl NotDatum for isize {}
impl NotDatum for f32 {}
impl NotDatum for f64 {}
impl<T> NotDatum for Option<T> {}
impl<T, E> NotDatum for Result<T, E> {}
impl<T: ?Sized> NotDatum for core::cell::UnsafeCell<T> {}
impl<T: ?Sized> NotDatum for core::cell::Cell<T> {}
impl<T: ?Sized> NotDatum for core::cell::RefCell<T> {}
impl<T: ?Sized> NotDatum for &T {}
impl<T: ?Sized> NotDatum for &mut T {}
impl<T: ?Sized> NotDatum for *const T {}
impl<T: ?Sized> NotDatum for *mut T {}
impl<T, const N: usize> NotDatum for [T; N] {}
#[cfg(feature = "alloc")]
impl NotDatum for alloc::string::String {}
#[cfg(feature = "alloc")]
impl<T> NotDatum for Vec<T> {}
#[cfg(feature = "alloc")]
impl<T: ?Sized> NotDatum for Rc<T> {}
#[cfg(feature = "std")]
impl<T: ?Sized> NotDatum for Arc<T> {}
#[cfg(feature = "std")]
impl<T: ?Sized> NotDatum for Mutex<T> {}
#[cfg(feature = "std")]
impl<T: ?Sized> NotDatum for RwLock<T> {}
impl NotDatum for LinearState {}
impl NotDatum for AngularState {}
impl NotDatum for LinearCommand {}
impl NotDatum for AngularCommand {}
impl NotDatum for PositionDerivative {}
impl NotDatum for error::CannotConvert {}
impl NotDatum for Time {}
impl NotDatum for DimensionlessInteger {}
impl NotDatum for compile_time_integer::Zero {}
impl<T: compile_time_integer::Integer> NotDatum for compile_time_integer::OnePlus<T> {}
impl<T: compile_time_integer::Integer> NotDatum for compile_time_integer::NegativeOnePlus<T> {}
impl<T, MM, S> NotDatum for Quantity<T, MM, S>
where
MM: compile_time_integer::Integer,
S: compile_time_integer::Integer,
{
}
impl NotDatum for MotionProfilePiece {}
impl NotDatum for PIDKValues {}
impl NotDatum for PositionDerivativeDependentPIDKValues {}
impl<T: Not<Output = O>, O> Not for Datum<T> {
type Output = Datum<O>;
fn not(self) -> Datum<O> {
Datum::new(self.time, !self.value)
}
}
impl<T: Neg<Output = O>, O> Neg for Datum<T> {
type Output = Datum<O>;
fn neg(self) -> Datum<O> {
Datum::new(self.time, -self.value)
}
}
impl<T: Add<TR, Output = O>, TR, O> Add<Datum<TR>> for Datum<T> {
type Output = Datum<O>;
fn add(self, other: Datum<TR>) -> Datum<O> {
let output_value = self.value + other.value;
let output_time = if self.time >= other.time {
self.time
} else {
other.time
};
Datum::new(output_time, output_value)
}
}
impl<T: AddAssign<TR>, TR> AddAssign<Datum<TR>> for Datum<T> {
fn add_assign(&mut self, other: Datum<TR>) {
self.value += other.value;
self.time = if self.time >= other.time {
self.time
} else {
other.time
};
}
}
impl<T: Add<TR, Output = O>, TR: NotDatum, O> Add<TR> for Datum<T> {
type Output = Datum<O>;
fn add(self, other: TR) -> Datum<O> {
let output_value = self.value + other;
Datum::new(self.time, output_value)
}
}
impl<T: AddAssign<TR>, TR: NotDatum> AddAssign<TR> for Datum<T> {
fn add_assign(&mut self, other: TR) {
self.value += other;
}
}
impl<T: Sub<TR, Output = O>, TR, O> Sub<Datum<TR>> for Datum<T> {
type Output = Datum<O>;
fn sub(self, other: Datum<TR>) -> Datum<O> {
let output_value = self.value - other.value;
let output_time = if self.time >= other.time {
self.time
} else {
other.time
};
Datum::new(output_time, output_value)
}
}
impl<T: SubAssign<TR>, TR> SubAssign<Datum<TR>> for Datum<T> {
fn sub_assign(&mut self, other: Datum<TR>) {
self.value -= other.value;
self.time = if self.time >= other.time {
self.time
} else {
other.time
};
}
}
impl<T: Sub<TR, Output = O>, TR: NotDatum, O> Sub<TR> for Datum<T> {
type Output = Datum<O>;
fn sub(self, other: TR) -> Datum<O> {
let output_value = self.value - other;
Datum::new(self.time, output_value)
}
}
impl<T: SubAssign<TR>, TR: NotDatum> SubAssign<TR> for Datum<T> {
fn sub_assign(&mut self, other: TR) {
self.value -= other;
}
}
impl<T: Mul<TR, Output = O>, TR, O> Mul<Datum<TR>> for Datum<T> {
type Output = Datum<O>;
fn mul(self, other: Datum<TR>) -> Datum<O> {
let output_value = self.value * other.value;
let output_time = if self.time >= other.time {
self.time
} else {
other.time
};
Datum::new(output_time, output_value)
}
}
impl<T: MulAssign<TR>, TR> MulAssign<Datum<TR>> for Datum<T> {
fn mul_assign(&mut self, other: Datum<TR>) {
self.value *= other.value;
self.time = if self.time >= other.time {
self.time
} else {
other.time
};
}
}
impl<T: Mul<TR, Output = O>, TR: NotDatum, O> Mul<TR> for Datum<T> {
type Output = Datum<O>;
fn mul(self, other: TR) -> Datum<O> {
let output_value = self.value * other;
Datum::new(self.time, output_value)
}
}
impl<T: MulAssign<TR>, TR: NotDatum> MulAssign<TR> for Datum<T> {
fn mul_assign(&mut self, other: TR) {
self.value *= other;
}
}
impl<T: Div<TR, Output = O>, TR, O> Div<Datum<TR>> for Datum<T> {
type Output = Datum<O>;
fn div(self, other: Datum<TR>) -> Datum<O> {
let output_value = self.value / other.value;
let output_time = if self.time >= other.time {
self.time
} else {
other.time
};
Datum::new(output_time, output_value)
}
}
impl<T: DivAssign<TR>, TR> DivAssign<Datum<TR>> for Datum<T> {
fn div_assign(&mut self, other: Datum<TR>) {
self.value /= other.value;
self.time = if self.time >= other.time {
self.time
} else {
other.time
};
}
}
impl<T: Div<TR, Output = O>, TR: NotDatum, O> Div<TR> for Datum<T> {
type Output = Datum<O>;
fn div(self, other: TR) -> Datum<O> {
let output_value = self.value / other;
Datum::new(self.time, output_value)
}
}
impl<T: DivAssign<TR>, TR: NotDatum> DivAssign<TR> for Datum<T> {
fn div_assign(&mut self, other: TR) {
self.value /= other;
}
}