pub mod dtd;
pub mod relaxng;
pub mod schematron;
pub mod xsd;
use std::fmt;
#[derive(Debug, Clone)]
pub struct ValidationResult {
pub is_valid: bool,
pub errors: Vec<ValidationError>,
pub warnings: Vec<ValidationError>,
}
#[derive(Debug, Clone)]
pub struct ValidationError {
pub message: String,
pub line: Option<usize>,
pub column: Option<usize>,
}
impl fmt::Display for ValidationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match (self.line, self.column) {
(Some(line), Some(col)) => write!(f, "{}:{}: {}", line, col, self.message),
(Some(line), None) => write!(f, "line {}: {}", line, self.message),
_ => write!(f, "{}", self.message),
}
}
}
impl fmt::Display for ValidationResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_valid {
write!(f, "valid")?;
} else {
write!(f, "invalid ({} error(s))", self.errors.len())?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validation_error_display_with_location() {
let err = ValidationError {
message: "missing required attribute".to_string(),
line: Some(5),
column: Some(10),
};
assert_eq!(err.to_string(), "5:10: missing required attribute");
}
#[test]
fn test_validation_error_display_line_only() {
let err = ValidationError {
message: "unexpected element".to_string(),
line: Some(3),
column: None,
};
assert_eq!(err.to_string(), "line 3: unexpected element");
}
#[test]
fn test_validation_error_display_no_location() {
let err = ValidationError {
message: "duplicate ID".to_string(),
line: None,
column: None,
};
assert_eq!(err.to_string(), "duplicate ID");
}
#[test]
fn test_validation_result_display() {
let valid = ValidationResult {
is_valid: true,
errors: vec![],
warnings: vec![],
};
assert_eq!(valid.to_string(), "valid");
let invalid = ValidationResult {
is_valid: false,
errors: vec![
ValidationError {
message: "error 1".to_string(),
line: None,
column: None,
},
ValidationError {
message: "error 2".to_string(),
line: None,
column: None,
},
],
warnings: vec![],
};
assert_eq!(invalid.to_string(), "invalid (2 error(s))");
}
}