Skip to content

Commit

Permalink
feat: inner option support
Browse files Browse the repository at this point in the history
  • Loading branch information
bonofiglio committed Sep 21, 2023
1 parent cf3998a commit dc2d6c4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
13 changes: 13 additions & 0 deletions garde/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,21 @@ pub struct Path {
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Kind {
None,
Key,
Index,
}

#[doc(hidden)]
#[derive(Default)]
pub struct NoKey(());

impl std::fmt::Display for NoKey {
fn fmt(&self, _: &mut std::fmt::Formatter) -> std::fmt::Result {
Ok(())
}
}

pub trait PathComponentKind: std::fmt::Display + ToCompactString + private::Sealed {
fn component_kind() -> Kind;
}
Expand All @@ -116,6 +127,7 @@ impl_path_component_kind!(@'a; &'a str => Key);
impl_path_component_kind!(@'a; Cow<'a, str> => Key);
impl_path_component_kind!(String => Key);
impl_path_component_kind!(CompactString => Key);
impl_path_component_kind!(NoKey => None);

impl<'a, T: PathComponentKind> private::Sealed for &'a T {}
impl<'a, T: PathComponentKind> PathComponentKind for &'a T {
Expand Down Expand Up @@ -204,6 +216,7 @@ impl std::fmt::Display for Path {
}
if let Some((kind, _)) = components.peek() {
match kind {
Kind::None => {}
Kind::Key => f.write_str(".")?,
Kind::Index => f.write_str("[")?,
}
Expand Down
17 changes: 16 additions & 1 deletion garde/src/rules/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//!
//! The entrypoint is the [`Inner`] trait. Implementing this trait for a type allows that type to be used with the `#[garde(inner(..))]` rule.
use crate::error::{NoKey, PathComponentKind};

pub fn apply<T, U, K, F>(field: &T, f: F)
where
T: Inner<U, Key = K>,
Expand All @@ -19,7 +21,7 @@ where
}

pub trait Inner<T> {
type Key;
type Key: PathComponentKind;

fn validate_inner<F>(&self, f: F)
where
Expand Down Expand Up @@ -60,3 +62,16 @@ impl<'a, T> Inner<T> for &'a [T] {
}
}
}

impl<T> Inner<T> for Option<T> {
type Key = NoKey;

fn validate_inner<F>(&self, mut f: F)
where
F: FnMut(&T, &Self::Key),
{
if let Some(item) = self {
f(item, &NoKey::default())
}
}
}

0 comments on commit dc2d6c4

Please sign in to comment.