1use {
4 crate::{Sigma, Test},
5 core::{fmt, marker::PhantomData},
6};
7
8pub trait CanBeInfinite {
10 fn check_finite(&self) -> bool;
12}
13
14pub type Finite<Input> = Sigma<Input, FiniteInvariant<Input>>;
16
17#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
19pub struct FiniteInvariant<Input: fmt::Debug + CanBeInfinite>(PhantomData<Input>);
20
21impl<Input: fmt::Debug + CanBeInfinite> Test<Input, 1> for FiniteInvariant<Input> {
22 const ADJECTIVE: &str = "finite";
23 type Error<'i>
24 = NotFinite
25 where
26 Input: 'i;
27
28 #[inline(always)]
29 fn test([input]: [&Input; 1]) -> Result<(), Self::Error<'_>> {
30 if input.check_finite() {
31 Ok(())
32 } else {
33 Err(NotFinite)
34 }
35 }
36}
37
38#[non_exhaustive]
40#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
41pub struct NotFinite;
42
43impl fmt::Display for NotFinite {
44 #[inline]
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(f, "`CanBeInfinite::check_finite(..)` returned `false`")
47 }
48}
49
50impl CanBeInfinite for f32 {
51 #[inline(always)]
52 fn check_finite(&self) -> bool {
53 self.is_finite()
54 }
55}
56
57impl CanBeInfinite for f64 {
58 #[inline(always)]
59 fn check_finite(&self) -> bool {
60 self.is_finite()
61 }
62}