sigma_types/
non_negative.rs1use {
4 crate::{Sigma, Test, Zero},
5 core::{fmt, marker::PhantomData},
6};
7
8pub type NonNegative<Input> = Sigma<Input, NonNegativeInvariant<Input>>;
10
11#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
13pub struct NonNegativeInvariant<Input: fmt::Debug + PartialOrd + Zero>(PhantomData<Input>);
14
15impl<Input: fmt::Debug + PartialOrd + Zero> Test<Input, 1> for NonNegativeInvariant<Input> {
16 const ADJECTIVE: &str = "non-negative";
17 type Error<'i>
18 = NotNonNegative<'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(NotNonNegative(input))
28 }
29 }
30}
31
32#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
34pub struct NotNonNegative<'i, Input: fmt::Debug + PartialOrd + Zero>(&'i Input);
35
36impl<Input: fmt::Debug + PartialOrd + Zero> fmt::Display for NotNonNegative<'_, 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}