Skip to main content

apple_quant_algorithmic/volume/zeroable/
checked.rs

1use std::cmp;
2
3use apple_quant_core::log::error;
4
5use crate::volume::{ZeroableExt, ZeroableVolume, ZERO_ERROR};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct ZeroableChecked<T: ZeroableVolume>(Option<T>);
9
10impl<T: ZeroableVolume> ZeroableChecked<T> {
11	pub const ZERO: Self = Self(None);
12
13	pub fn new(
14		t: Option<T>,
15	) -> Self {
16		Self(t)
17	}
18}
19
20impl<T: ZeroableVolume> ZeroableExt<T> for ZeroableChecked<T> {
21	fn as_optional_nonzero_ref(
22		&self,
23	) -> Option<&T> {
24		self.0.as_ref()
25	}
26
27	fn as_optional_nonzero_mut(
28		&mut self,
29	) -> Option<&mut T> {
30		self.0.as_mut()
31	}
32
33	fn into_optional_nonzero(
34		self,
35	) -> Option<T> {
36		self.0
37	}
38
39	fn as_zeroable(
40		&self,
41	) -> T {
42		self.0.unwrap_or(T::ZERO)
43	}
44
45	fn into_zeroable(
46		self,
47	) -> T {
48		self.0.unwrap_or(T::ZERO)
49	}
50
51	/// Always safe when using [`ZeroableChecked`].
52	fn as_nonzero_unchecked_ref(
53		&self,
54	) -> &T {
55		self.0
56			.as_ref()
57			.unwrap_or_else(|| {
58				error!("{ZERO_ERROR}");
59				panic!();
60			})
61	}
62
63	/// Always safe when using [`ZeroableChecked`].
64	fn as_nonzero_unchecked_mut(
65		&mut self,
66	) -> &mut T {
67		self.0
68			.as_mut()
69			.unwrap_or_else(|| {
70				error!("{ZERO_ERROR}");
71				panic!();
72			})
73	}
74
75	/// Always safe when using [`ZeroableChecked`].
76	fn into_nonzero_unchecked(
77		self,
78	) -> T {
79		self.0.unwrap_or_else(|| {
80			error!("{ZERO_ERROR}");
81			panic!();
82		})
83	}
84}
85
86impl<T: ZeroableVolume> PartialOrd for ZeroableChecked<T> {
87	#[inline]
88	fn partial_cmp(
89		&self,
90		other: &Self,
91	) -> Option<cmp::Ordering> {
92		Some(self.cmp(other))
93	}
94}
95
96impl<T: ZeroableVolume> Ord for ZeroableChecked<T> {
97	fn cmp(
98		&self,
99		other: &Self,
100	) -> cmp::Ordering {
101		let lhs = self.as_zeroable();
102		let rhs = other.as_zeroable();
103
104		lhs.cmp(&rhs)
105	}
106}