prost_validate/
lib.rs

1mod bytes;
2mod error;
3pub mod errors;
4mod string;
5#[doc(hidden)]
6pub mod utils;
7
8#[doc(hidden)]
9pub use bytes::ValidateBytesExt;
10pub use error::*;
11#[doc(hidden)]
12pub use string::ValidateStringExt;
13#[doc(hidden)]
14pub use utils::VecExt;
15
16/// Re-export of the `Validator` derive macro if the `derive` feature is enabled.
17#[cfg(feature = "derive")]
18pub use prost_validate_derive::Validator;
19
20/// A type alias for `Result` with the error type defaulting to `Error`.
21pub type Result<T = (), E = Error> = core::result::Result<T, E>;
22
23/// The trait implemented by types that require validation logic.
24pub trait Validator: Send + Sync {
25    fn validate(&self) -> Result {
26        Ok(())
27    }
28}
29
30// NoopValidator is the same trait as `Validator`.
31// It is used to implement the default behavior of a type that does not implement the `Validator` trait.
32#[doc(hidden)]
33pub trait NoopValidator {
34    fn validate(&self) -> Result {
35        Ok(())
36    }
37}
38
39// Implement `NoopValidator` for any type.
40impl<T: ?Sized> NoopValidator for T {}
41
42// SafeValidator is a wrapper for any value.
43// It is used to be able to call the validate method on any value.
44#[doc(hidden)]
45pub struct SafeValidator<'a, T: ?Sized>(pub &'a T);
46
47// Implement the `validate` method only for types that implement the Validator trait.
48impl<T: ?Sized + Validator> SafeValidator<'_, T> {
49    pub fn validate(&self) -> Result {
50        Validator::validate(self.0)
51    }
52}
53
54/// Validate any value if it implements the Validator trait.
55/// If the value does not implement the Validator trait, it will return Ok(()).
56#[macro_export]
57macro_rules! validate {
58    ($value:tt) => {{
59        use ::prost_validate::NoopValidator;
60        use std::ops::Deref;
61        ::prost_validate::SafeValidator($value.deref()).validate()
62    }};
63}
64
65#[cfg(test)]
66mod tests {
67    pub struct A {}
68
69    impl prost_validate::Validator for A {
70        fn validate(&self) -> prost_validate::Result {
71            Err(prost_validate::Error::new(
72                "",
73                prost_validate::errors::Error::InvalidRules("failed".to_string()),
74            ))
75        }
76    }
77
78    pub struct B {}
79
80    #[test]
81    fn test_validator() {
82        let a = &A {};
83        assert!(prost_validate::validate!(a).is_err());
84    }
85    #[test]
86    fn test_validator_double_ref() {
87        let a = &&A {};
88        assert!(prost_validate::validate!(a).is_err());
89    }
90    #[test]
91    fn test_non_validator() {
92        let b = &B {};
93        assert!(prost_validate::validate!(b).is_ok());
94    }
95    #[test]
96    fn test_scalar() {
97        let c = &42;
98        assert!(prost_validate::validate!(c).is_ok());
99    }
100}