garde/rules/
inner.rs

1//! Inner type validation.
2//!
3//! ```rust
4//! #[derive(garde::Validate)]
5//! struct Test {
6//!     #[garde(inner(length(min=1)))]
7//!     v: Vec<String>,
8//! }
9//! ```
10//!
11//! The entrypoint is the [`Inner`] trait. Implementing this trait for a type allows that type to be used with the `#[garde(inner(..))]` rule.
12
13use crate::error::{NoKey, PathComponentKind};
14
15pub fn apply<T, U, K, F>(field: &T, f: F)
16where
17    T: Inner<U, Key = K>,
18    F: FnMut(&U, &K),
19{
20    field.validate_inner(f)
21}
22
23pub trait Inner<T> {
24    type Key: PathComponentKind;
25
26    fn validate_inner<F>(&self, f: F)
27    where
28        F: FnMut(&T, &Self::Key);
29}
30
31impl<T> Inner<T> for Vec<T> {
32    type Key = usize;
33
34    fn validate_inner<F>(&self, f: F)
35    where
36        F: FnMut(&T, &Self::Key),
37    {
38        self.as_slice().validate_inner(f)
39    }
40}
41
42impl<const N: usize, T> Inner<T> for [T; N] {
43    type Key = usize;
44
45    fn validate_inner<F>(&self, f: F)
46    where
47        F: FnMut(&T, &Self::Key),
48    {
49        self.as_slice().validate_inner(f)
50    }
51}
52
53impl<T> Inner<T> for &[T] {
54    type Key = usize;
55
56    fn validate_inner<F>(&self, mut f: F)
57    where
58        F: FnMut(&T, &Self::Key),
59    {
60        for (index, item) in self.iter().enumerate() {
61            f(item, &index);
62        }
63    }
64}
65
66impl<T> Inner<T> for Option<T> {
67    type Key = NoKey;
68
69    fn validate_inner<F>(&self, mut f: F)
70    where
71        F: FnMut(&T, &Self::Key),
72    {
73        if let Some(item) = self {
74            f(item, &NoKey::default())
75        }
76    }
77}