use std::cmp;
use apple_quant_core::log::error;
use crate::volume::{ZeroableExt, ZeroableVolume, ZERO_ERROR};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ZeroableChecked<T: ZeroableVolume>(Option<T>);
impl<T: ZeroableVolume> ZeroableChecked<T> {
pub const ZERO: Self = Self(None);
pub fn new(
t: Option<T>,
) -> Self {
Self(t)
}
}
impl<T: ZeroableVolume> ZeroableExt<T> for ZeroableChecked<T> {
fn as_optional_nonzero_ref(
&self,
) -> Option<&T> {
self.0.as_ref()
}
fn as_optional_nonzero_mut(
&mut self,
) -> Option<&mut T> {
self.0.as_mut()
}
fn into_optional_nonzero(
self,
) -> Option<T> {
self.0
}
fn as_zeroable(
&self,
) -> T {
self.0.unwrap_or(T::ZERO)
}
fn into_zeroable(
self,
) -> T {
self.0.unwrap_or(T::ZERO)
}
fn as_nonzero_unchecked_ref(
&self,
) -> &T {
self.0
.as_ref()
.unwrap_or_else(|| {
error!("{ZERO_ERROR}");
panic!();
})
}
fn as_nonzero_unchecked_mut(
&mut self,
) -> &mut T {
self.0
.as_mut()
.unwrap_or_else(|| {
error!("{ZERO_ERROR}");
panic!();
})
}
fn into_nonzero_unchecked(
self,
) -> T {
self.0.unwrap_or_else(|| {
error!("{ZERO_ERROR}");
panic!();
})
}
}
impl<T: ZeroableVolume> PartialOrd for ZeroableChecked<T> {
#[inline]
fn partial_cmp(
&self,
other: &Self,
) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<T: ZeroableVolume> Ord for ZeroableChecked<T> {
fn cmp(
&self,
other: &Self,
) -> cmp::Ordering {
let lhs = self.as_zeroable();
let rhs = other.as_zeroable();
lhs.cmp(&rhs)
}
}