1use core::{fmt, marker::PhantomData};
4
5#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct All<Invariant: crate::Test<Input::Item, 1>, Input: IntoIterator + fmt::Debug>(
8 PhantomData<Invariant>,
9 PhantomData<Input>,
10)
11where
12 Input::Item: fmt::Debug,
13 for<'i> &'i Input: IntoIterator<Item = &'i Input::Item>;
14
15impl<Invariant: crate::Test<Input::Item, 1>, Input: IntoIterator + fmt::Debug> crate::Test<Input, 1>
16 for All<Invariant, Input>
17where
18 Input::Item: fmt::Debug,
19 for<'i> &'i Input: IntoIterator<Item = &'i Input::Item>,
20{
21 const ADJECTIVE: &str = "all valid";
22
23 type Error<'i>
24 = NotAll<'i, Input::Item, Invariant>
25 where
26 Input: 'i;
27
28 #[inline]
29 fn test([input]: [&Input; 1]) -> Result<(), Self::Error<'_>> {
30 for (index, element) in input.into_iter().enumerate() {
31 match Invariant::test([element]) {
32 Ok(()) => {}
33 Err(error) => {
34 return Err(NotAll {
35 element,
36 error,
37 index,
38 });
39 }
40 }
41 }
42 Ok(())
43 }
44}
45
46#[non_exhaustive]
48#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
49pub struct NotAll<'i, Item: fmt::Debug, Invariant: crate::Test<Item, 1>> {
50 element: &'i Item,
52 error: Invariant::Error<'i>,
54 index: usize,
57}
58
59impl<Item: fmt::Debug, Invariant: crate::Test<Item, 1>> fmt::Display
60 for NotAll<'_, Item, Invariant>
61{
62 #[inline]
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 #![expect(
65 clippy::use_debug,
66 reason = "Intentional and informative, not just forgotten print-debugging"
67 )]
68
69 let Self {
70 element,
71 ref error,
72 index,
73 } = *self;
74 write!(
75 f,
76 "Element #{index} ({element:#?}) was not {}: {error}",
77 Invariant::ADJECTIVE,
78 )
79 }
80}