use crate::*;
use proto_types::protovalidate::*;
pub trait ValidationResultExt {
#[doc(hidden)]
#[allow(private_interfaces)]
const SEALED: Sealed;
fn is_valid(&self) -> bool;
fn is_fail_fast(&self) -> bool;
}
impl ValidationResultExt for ValidationResult {
#[doc(hidden)]
#[allow(private_interfaces)]
const SEALED: Sealed = Sealed;
#[inline]
fn is_valid(&self) -> bool {
match self {
Ok(outcome) => matches!(outcome, IsValid::Yes),
Err(_) => false,
}
}
#[inline]
fn is_fail_fast(&self) -> bool {
self.is_err()
}
}
#[derive(Debug, Clone, Copy)]
pub struct FailFast;
bool_enum!(pub IsValid, doc = r"A boolean-like enum that represents validation status. It supports all of the bit operators.
For more information on the boolean-like features of this enum, you can refer to the [`bool-enum`](::bool_enum) documentation.
");
impl IsValid {
#[must_use]
#[inline]
pub fn is_valid(&self) -> bool {
**self
}
}
pub type ValidationResult = Result<IsValid, FailFast>;
pub trait Validator<T: ?Sized>: Send + Sync {
type Target: ToOwned + ?Sized;
#[doc(hidden)]
#[inline]
#[cold]
fn __cel_rules(&self) -> Vec<CelRule> {
vec![]
}
#[inline]
#[cold]
fn schema(&self) -> Option<ValidatorSchema> {
None
}
#[inline]
#[cold]
fn check_consistency(&self) -> Result<(), Vec<ConsistencyError>> {
Ok(())
}
#[cfg(feature = "cel")]
#[inline]
#[cold]
fn check_cel_programs_with(
&self,
_val: <Self::Target as ToOwned>::Owned,
) -> Result<(), Vec<CelError>> {
Ok(())
}
#[cfg(feature = "cel")]
#[inline]
#[cold]
#[doc(hidden)]
fn __check_cel_programs(&self) -> Result<(), Vec<CelError>> {
Ok(())
}
#[inline]
fn validate(&self, val: &Self::Target) -> Result<(), ValidationErrors> {
let mut ctx = ValidationCtx::default();
let _ = self.execute_validation(&mut ctx, Some(val));
if ctx.violations.is_empty() {
Ok(())
} else {
Err(ctx.violations)
}
}
#[inline]
fn validate_option(&self, val: Option<&Self::Target>) -> Result<(), ValidationErrors> {
let mut ctx = ValidationCtx::default();
let _ = self.execute_validation(&mut ctx, val);
if ctx.violations.is_empty() {
Ok(())
} else {
Err(ctx.violations)
}
}
#[inline]
fn validate_with_ctx(
&self,
mut ctx: ValidationCtx,
val: &Self::Target,
) -> Result<(), ValidationErrors> {
let _ = self.execute_validation(&mut ctx, Some(val));
if ctx.violations.is_empty() {
Ok(())
} else {
Err(ctx.violations)
}
}
#[inline]
fn validate_option_with_ctx(
&self,
mut ctx: ValidationCtx,
val: Option<&Self::Target>,
) -> Result<(), ValidationErrors> {
let _ = self.execute_validation(&mut ctx, val);
if ctx.violations.is_empty() {
Ok(())
} else {
Err(ctx.violations)
}
}
fn execute_validation(
&self,
ctx: &mut ValidationCtx,
val: Option<&Self::Target>,
) -> ValidationResult;
}
pub trait ValidatorBuilderFor<T: ?Sized>: Default {
type Validator: Validator<T>;
fn build_validator(self) -> Self::Validator;
}
pub trait ProtoValidation {
type Target: ?Sized;
type Stored: Borrow<Self::Target>;
type Validator: Validator<Self, Target = Self::Target> + Clone + Default;
type ValidatorBuilder: ValidatorBuilderFor<Self, Validator = Self::Validator>;
#[doc(hidden)]
const HAS_DEFAULT_VALIDATOR: bool = false;
#[doc(hidden)]
const HAS_SHALLOW_VALIDATION: bool = false;
#[doc(hidden)]
type UniqueStore<'a>: UniqueStore<'a, Item = Self::Target>
where
Self: 'a;
#[inline]
#[doc(hidden)]
fn __make_unique_store<'a>(_validator: &Self::Validator, cap: usize) -> Self::UniqueStore<'a>
where
Self: 'a,
{
Self::UniqueStore::default_with_capacity(cap)
}
#[inline]
#[must_use]
fn validator_builder() -> Self::ValidatorBuilder {
Self::ValidatorBuilder::default()
}
#[inline]
fn validator_from_closure<F, FinalBuilder>(config_fn: F) -> Self::Validator
where
F: FnOnce(Self::ValidatorBuilder) -> FinalBuilder,
FinalBuilder: ValidatorBuilderFor<Self, Validator = Self::Validator>,
{
let initial_builder = Self::validator_builder();
config_fn(initial_builder).build_validator()
}
}
pub(crate) trait IsDefault: Default + PartialEq {
fn is_default(&self) -> bool {
(*self) == Self::default()
}
}
impl<T: Default + PartialEq> IsDefault for T {}
pub struct FnValidator<F, T: ?Sized> {
func: F,
_phantom: PhantomData<T>,
}
impl<F, T> Validator<T> for FnValidator<F, T>
where
T: ToOwned + ?Sized + Send + Sync,
F: Fn(&mut ValidationCtx, Option<&T>) -> ValidationResult + Send + Sync,
{
type Target = T;
#[inline]
fn execute_validation(
&self,
ctx: &mut ValidationCtx,
val: Option<&Self::Target>,
) -> ValidationResult {
(self.func)(ctx, val)
}
}
#[inline]
pub const fn from_fn<T, F>(f: F) -> FnValidator<F, T>
where
T: ?Sized,
F: Fn(&mut ValidationCtx, Option<&T>) -> ValidationResult,
{
FnValidator {
func: f,
_phantom: PhantomData,
}
}
type ErrorMessages<T> = Box<BTreeMap<T, FixedStr>>;
#[inline(never)]
#[cold]
#[allow(clippy::unnecessary_box_returns)]
pub(crate) fn collect_error_messages<V, M>(
error_messages: impl IntoIterator<Item = (V, M)>,
) -> ErrorMessages<V>
where
V: Ord + Eq,
M: Into<FixedStr>,
{
let map: BTreeMap<V, FixedStr> = error_messages
.into_iter()
.map(|(id, msg)| (id, msg.into()))
.collect();
Box::new(map)
}
mod builder_internals;
#[doc(hidden)]
use builder_internals::*;
pub mod any;
pub use any::*;
pub mod bool;
pub use bool::*;
pub mod bytes;
pub use bytes::*;
mod cel;
#[doc(inline)]
pub use cel::*;
pub mod duration;
pub use duration::*;
pub mod enums;
pub use enums::*;
mod field_context;
#[doc(inline)]
pub use field_context::*;
pub mod map;
pub use map::*;
pub mod message;
pub use message::*;
pub mod repeated;
pub use repeated::*;
pub mod string;
pub use string::*;
pub mod timestamp;
pub use timestamp::*;
pub mod floats;
pub use floats::*;
pub mod integers;
pub use integers::*;
pub mod field_mask;
pub use field_mask::*;
mod lookup;
pub use lookup::*;
mod oneof;
#[doc(inline)]
pub use oneof::*;
mod violations;
#[doc(inline)]
pub use violations::*;