sigma_types/
negative.rs

1//! Negative terms (defined by comparison to zero).
2
3use {
4    crate::{Sigma, Test, Zero},
5    core::{fmt, marker::PhantomData},
6};
7
8/// Negative terms (defined by comparison to zero).
9pub type Negative<Input> = Sigma<Input, NegativeInvariant<Input>>;
10
11/// Negative terms (defined by comparison to zero).
12#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
13pub struct NegativeInvariant<Input: fmt::Debug + PartialOrd + Zero>(PhantomData<Input>);
14
15impl<Input: fmt::Debug + PartialOrd + Zero> Test<Input, 1> for NegativeInvariant<Input> {
16    const ADJECTIVE: &str = "positive";
17    type Error<'i>
18        = NotNegative<'i, Input>
19    where
20        Input: 'i;
21
22    #[inline(always)]
23    fn test([input]: [&Input; 1]) -> Result<(), Self::Error<'_>> {
24        if *input < Input::ZERO {
25            Ok(())
26        } else {
27            Err(NotNegative(input))
28        }
29    }
30}
31
32/// A term expected to be positive was not.
33#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
34pub struct NotNegative<'i, Input: fmt::Debug + PartialOrd + Zero>(&'i Input);
35
36impl<Input: fmt::Debug + PartialOrd + Zero> fmt::Display for NotNegative<'_, Input> {
37    #[inline]
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        #![expect(
40            clippy::use_debug,
41            reason = "Intentional and informative, not just forgotten print-debugging"
42        )]
43
44        let Self(z) = *self;
45        write!(f, "{z:#?} >= {:#?}", Input::ZERO)
46    }
47}