use super::context::ValidationContext;
use crate::ast::{ASTContext, DefaultIn, Document};
use crate::error::Result;
use crate::visit::{ComposedVisitor, VisitNode, Visitor};
use std::borrow::Borrow;
pub trait ValidationRule<'a>: Visitor<'a, ValidationContext<'a>> + DefaultIn<'a> {
#[inline]
fn validate(ctx: &'a ASTContext, document: &'a Document<'a>) -> Result<()> {
let mut validation = ValidationContext::new(ctx);
let mut visitor = Self::default_in(&ctx.arena);
document.visit(&mut validation, &mut visitor);
validation.to_result()
}
}
impl<'a, A, B> DefaultIn<'a> for ComposedVisitor<'a, ValidationContext<'a>, A, B>
where
A: ValidationRule<'a>,
B: ValidationRule<'a>,
{
#[inline]
fn default_in(arena: &'a bumpalo::Bump) -> Self {
ComposedVisitor::new(A::default_in(arena), B::default_in(arena))
}
}
impl<'a, A, B> ValidationRule<'a> for ComposedVisitor<'a, ValidationContext<'a>, A, B>
where
A: ValidationRule<'a>,
B: ValidationRule<'a>,
{
}
pub trait ValidateNode<'a>
where
Self: Borrow<Document<'a>>,
{
#[inline]
fn validate<Rule: ValidationRule<'a>>(&'a self, ctx: &'a ASTContext) -> Result<()> {
Rule::validate(ctx, self.borrow())
}
}
impl<'a> ValidateNode<'a> for Document<'a> {}