sigma_types/
all.rs

1//! Iterable data structure in which each element satisfies a given invariant.
2
3use core::{fmt, marker::PhantomData};
4
5/// Iterable data structure in which each element satisfies a given invariant.
6#[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/// At least one element in an iterator did not satisfy the given invariant.
47#[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    /// Invalid element in the iterator.
51    element: &'i Item,
52    /// Error indicating why this element wasn't valid.
53    error: Invariant::Error<'i>,
54    /// After how many other elements
55    /// did we see the this element?
56    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}