refining_length/
predicates.rs1use core::{fmt, marker::PhantomData};
4
5use refining_core::{
6 logical::{And, Not},
7 predicate::Predicate,
8};
9
10use crate::length::HasLength;
11
12pub struct LengthEqual<const N: usize> {
14 private: PhantomData<()>,
15}
16
17impl<const N: usize, T: HasLength + ?Sized> Predicate<T> for LengthEqual<N> {
18 fn check(value: &T) -> bool {
19 value.length() == N
20 }
21
22 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
23 write!(formatter, "value with length == {N}")
24 }
25
26 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
27 write!(formatter, "length::eq<{N}>")
28 }
29}
30
31pub struct LengthNotEqual<const N: usize> {
33 private: PhantomData<()>,
34}
35
36impl<const N: usize, T: HasLength + ?Sized> Predicate<T> for LengthNotEqual<N> {
37 fn check(value: &T) -> bool {
38 value.length() != N
39 }
40
41 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
42 write!(formatter, "value with length != {N}")
43 }
44
45 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(formatter, "length::ne<{N}>")
47 }
48}
49
50pub struct LengthLess<const N: usize> {
52 private: PhantomData<()>,
53}
54
55impl<const N: usize, T: HasLength + ?Sized> Predicate<T> for LengthLess<N> {
56 fn check(value: &T) -> bool {
57 value.length() < N
58 }
59
60 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(formatter, "value with length < {N}")
62 }
63
64 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
65 write!(formatter, "length::lt<{N}>")
66 }
67}
68
69pub struct LengthGreater<const N: usize> {
71 private: PhantomData<()>,
72}
73
74impl<const N: usize, T: HasLength + ?Sized> Predicate<T> for LengthGreater<N> {
75 fn check(value: &T) -> bool {
76 value.length() > N
77 }
78
79 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
80 write!(formatter, "value with length > {N}")
81 }
82
83 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
84 write!(formatter, "length::gt<{N}>")
85 }
86}
87
88pub struct LengthLessOrEqual<const N: usize> {
90 private: PhantomData<()>,
91}
92
93impl<const N: usize, T: HasLength + ?Sized> Predicate<T> for LengthLessOrEqual<N> {
94 fn check(value: &T) -> bool {
95 value.length() <= N
96 }
97
98 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(formatter, "value with length <= {N}")
100 }
101
102 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
103 write!(formatter, "length::le<{N}>")
104 }
105}
106
107pub struct LengthGreaterOrEqual<const N: usize> {
109 private: PhantomData<()>,
110}
111
112impl<const N: usize, T: HasLength + ?Sized> Predicate<T> for LengthGreaterOrEqual<N> {
113 fn check(value: &T) -> bool {
114 value.length() >= N
115 }
116
117 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
118 write!(formatter, "value with length >= {N}")
119 }
120
121 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
122 write!(formatter, "length::ge<{N}>")
123 }
124}
125
126pub type LengthOpen<const M: usize, const N: usize> = And<LengthGreater<M>, LengthLess<N>>;
128
129pub type LengthClosedOpen<const M: usize, const N: usize> =
131 And<LengthGreaterOrEqual<M>, LengthLess<N>>;
132
133pub type LengthOpenClosed<const M: usize, const N: usize> =
135 And<LengthGreater<M>, LengthLessOrEqual<N>>;
136
137pub type LengthClosed<const M: usize, const N: usize> =
139 And<LengthGreaterOrEqual<M>, LengthLessOrEqual<N>>;
140
141pub const ZERO: usize = 0;
143
144pub type LengthZero = LengthEqual<ZERO>;
146
147pub type LengthNonZero = LengthNotEqual<ZERO>;
149
150pub struct LengthModulo<const D: usize, const M: usize> {
152 private: PhantomData<()>,
153}
154
155impl<const D: usize, const M: usize, T: HasLength + ?Sized> Predicate<T> for LengthModulo<D, M> {
156 fn check(value: &T) -> bool {
157 value.length() % D == M
158 }
159
160 fn expect(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
161 write!(formatter, "value with length % {D} == {M}")
162 }
163
164 fn expect_code(formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
165 write!(formatter, "length::mod<{D}, {M}>")
166 }
167}
168
169pub type LengthDivisible<const D: usize> = LengthModulo<D, ZERO>;
171
172pub const TWO: usize = 2;
174
175pub type LengthEven = LengthDivisible<TWO>;
177
178pub type LengthOdd = Not<LengthEven>;