use super::super::BoundValidationContext;
use super::super::ExecutionError;
use super::super::ExecutionErrorKind;
use super::super::InputType;
use super::super::PreparedOutcome;
use super::super::PreparedValidator;
use super::super::ValidationValue;
use crate::Validator;
use crate::ViolationDraft;
pub(in crate::binding) struct TextValidatorAdapter<V, M> {
validator: V,
map_error: M,
}
impl<V, M> TextValidatorAdapter<V, M> {
#[must_use]
#[inline]
pub(in crate::binding) const fn new(validator: V, map_error: M) -> Self {
Self { validator, map_error }
}
}
impl<V, M> PreparedValidator for TextValidatorAdapter<V, M>
where
V: Validator<str, ()> + Send + Sync + 'static,
M: Fn(V::Error) -> ViolationDraft + Send + Sync + 'static,
{
#[inline]
fn input_type(&self) -> InputType {
InputType::Text
}
#[inline]
fn dependency_specs(&self) -> &'static [super::super::DependencySpec] {
&[]
}
fn validate(
&self,
value: ValidationValue<'_>,
_: &BoundValidationContext<'_>,
) -> Result<PreparedOutcome, ExecutionError> {
let text = value
.as_text()
.ok_or_else(|| ExecutionError::new(ExecutionErrorKind::InputTypeMismatch))?;
match self.validator.validate(text, &()) {
Ok(()) => Ok(PreparedOutcome::valid()),
Err(error) => Ok(PreparedOutcome::invalid(vec![(self.map_error)(error)])
.expect("a domain error maps to one violation draft")),
}
}
}