apple-quant-algorithmic 0.4.0

Apple Quant's algorithmic library.
Documentation
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)
	}

	/// Always safe when using [`ZeroableChecked`].
	fn as_nonzero_unchecked_ref(
		&self,
	) -> &T {
		self.0
			.as_ref()
			.unwrap_or_else(|| {
				error!("{ZERO_ERROR}");
				panic!();
			})
	}

	/// Always safe when using [`ZeroableChecked`].
	fn as_nonzero_unchecked_mut(
		&mut self,
	) -> &mut T {
		self.0
			.as_mut()
			.unwrap_or_else(|| {
				error!("{ZERO_ERROR}");
				panic!();
			})
	}

	/// Always safe when using [`ZeroableChecked`].
	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)
	}
}