use bistun_core::{CapabilityManifest, LmsError, TraitKey, TraitValue};
pub fn verify(manifest: &CapabilityManifest) -> Result<(), LmsError> {
if manifest.traits.is_empty() {
return Err(LmsError::IntegrityViolation {
pipeline_step: "Phase 4: Integrity Check".to_string(),
context: manifest.resolved_locale.clone(),
reason: "Manifest traits dictionary cannot be empty".to_string(),
});
}
let has_bidi =
manifest.traits.get(&TraitKey::HasBidiElements) == Some(&TraitValue::Boolean(true));
let requires_shaping =
manifest.traits.get(&TraitKey::RequiresShaping) == Some(&TraitValue::Boolean(true));
if has_bidi && !requires_shaping && manifest.resolved_locale != "he" {
return Err(LmsError::IntegrityViolation {
pipeline_step: "Phase 4: Integrity Check".to_string(),
context: manifest.resolved_locale.clone(),
reason: "Bidirectional layouts inherently require shaping algorithms, but REQUIRES_SHAPING is false".to_string(),
});
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_verify_passes_valid_manifest() {
let mut manifest = CapabilityManifest::new("ar-EG".to_string());
manifest.traits.insert(TraitKey::HasBidiElements, TraitValue::Boolean(true));
manifest.traits.insert(TraitKey::RequiresShaping, TraitValue::Boolean(true));
assert!(verify(&manifest).is_ok());
}
#[test]
fn test_verify_catches_empty_manifest() {
let manifest = CapabilityManifest::new("en-US".to_string());
let err = verify(&manifest).unwrap_err();
assert!(matches!(err, LmsError::IntegrityViolation { .. }));
}
#[test]
fn test_verify_catches_bidi_shaping_contradiction() {
let mut manifest = CapabilityManifest::new("ar-EG".to_string());
manifest.traits.insert(TraitKey::HasBidiElements, TraitValue::Boolean(true));
manifest.traits.insert(TraitKey::RequiresShaping, TraitValue::Boolean(false));
let err = verify(&manifest).unwrap_err();
assert!(matches!(err, LmsError::IntegrityViolation { .. }));
}
}