use std::path::Path;
use super::document::TomlDocument;
use super::error::LoaderError;
impl TomlDocument {
pub(super) fn validate(&self, path: &Path) -> Result<(), LoaderError> {
validate_string(&self.version, "version", path)?;
for (i, op) in self.ops.iter().enumerate() {
let prefix = format!("ops[{i}]");
validate_string(&op.name, &format!("{prefix}.name"), path)?;
validate_string(&op.output, &format!("{prefix}.output"), path)?;
validate_string(
&op.reference_impl_id,
&format!("{prefix}.reference_impl_id"),
path,
)?;
for (j, input) in op.inputs.iter().enumerate() {
validate_string(input, &format!("{prefix}.inputs[{j}]"), path)?;
}
for (j, law) in op.declared_laws.iter().enumerate() {
validate_string(law, &format!("{prefix}.declared_laws[{j}]"), path)?;
}
}
for (i, w) in self.witnesses.iter().enumerate() {
let prefix = format!("witnesses[{i}]");
validate_string(&w.op, &format!("{prefix}.op"), path)?;
validate_string(&w.distribution, &format!("{prefix}.distribution"), path)?;
if w.count > 1_000_000 {
return Err(LoaderError::UnreasonableCount { count: w.count });
}
}
for (i, d) in self.defendants.iter().enumerate() {
let prefix = format!("defendants[{i}]");
validate_string(&d.name, &format!("{prefix}.name"), path)?;
validate_string(&d.source_url, &format!("{prefix}.source_url"), path)?;
validate_string(&d.version, &format!("{prefix}.version"), path)?;
validate_string(
&d.expected_outcome,
&format!("{prefix}.expected_outcome"),
path,
)?;
}
for (i, law) in self.laws.iter().enumerate() {
let prefix = format!("laws[{i}]");
validate_string(&law.name, &format!("{prefix}.name"), path)?;
validate_string(&law.ariadne, &format!("{prefix}.ariadne"), path)?;
validate_string(&law.predicate, &format!("{prefix}.predicate"), path)?;
validate_string(
&law.witness_strategy,
&format!("{prefix}.witness_strategy"),
path,
)?;
}
for (i, rule) in self.independence.iter().enumerate() {
let prefix = format!("independence[{i}]");
validate_string(&rule.pattern, &format!("{prefix}.pattern"), path)?;
validate_string(
&rule.classification,
&format!("{prefix}.classification"),
path,
)?;
validate_string(&rule.severity, &format!("{prefix}.severity"), path)?;
}
Ok(())
}
}
fn validate_string(s: &str, field: &str, path: &Path) -> Result<(), LoaderError> {
for (byte_offset, byte) in s.bytes().enumerate() {
if !matches!(byte, b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b' ' | b'.' | b'_' | b'/' | b'-')
{
return Err(LoaderError::UnsafeString {
field: field.to_string(),
path: path.to_path_buf(),
byte_offset,
});
}
}
Ok(())
}