mod builder;
mod skeleton;
mod validation;
use std::io::{BufRead, Seek, SeekFrom};
use std::sync::Arc;
use crate::error::{Result, StructuredError};
use crate::event::StreamingParser;
use crate::schema::types::CompiledSchema;
pub use self::skeleton::{DocumentSkeleton, ElementSkeleton};
use self::builder::SkeletonBuilder;
use super::ValidationMode;
use super::streaming::ValidationOptions;
#[deprecated(
since = "0.5.0",
note = "TwoPassSchemaValidator is no longer recommended. Use OnePassSchemaValidator (or StreamValidator) instead for better performance."
)]
pub struct TwoPassSchemaValidator {
pub(crate) schema: Arc<CompiledSchema>,
pub(crate) options: ValidationOptions,
pub(crate) mode: ValidationMode,
pub(crate) max_errors: usize,
}
#[allow(deprecated)]
impl TwoPassSchemaValidator {
pub fn new(schema: Arc<CompiledSchema>) -> Self {
Self {
schema,
options: ValidationOptions::default(),
mode: ValidationMode::Strict,
max_errors: 0,
}
}
pub fn with_mode(mut self, mode: ValidationMode) -> Self {
self.mode = mode;
self
}
pub fn with_options(mut self, options: ValidationOptions) -> Self {
self.options = options;
self
}
pub fn with_max_errors(mut self, max: usize) -> Self {
self.max_errors = max;
self
}
pub fn validate<R: BufRead + Seek>(self, mut reader: R) -> Result<Vec<StructuredError>> {
let skeleton = Self::build_skeleton(&mut reader)?;
let _ = reader.seek(SeekFrom::Start(0));
self.validate_with_skeleton(&skeleton)
}
fn build_skeleton<R: BufRead>(reader: &mut R) -> Result<DocumentSkeleton> {
let mut parser = StreamingParser::new(reader);
let builder = SkeletonBuilder::new();
parser.add_handler(Box::new(builder));
parser.parse()?;
let handlers = parser.into_handlers();
for handler in handlers {
if let Ok(builder) = handler.as_any().downcast::<SkeletonBuilder>() {
return Ok(builder.into_skeleton());
}
}
Ok(DocumentSkeleton::new())
}
fn validate_with_skeleton(&self, skeleton: &DocumentSkeleton) -> Result<Vec<StructuredError>> {
let mut errors = Vec::new();
if let Some(root_index) = skeleton.root_index {
self.validate_node_recursive(skeleton, root_index, None, &mut errors);
}
Ok(errors)
}
}
#[cfg(test)]
mod tests;