use crate::parser::location::SourceRef;
use thiserror::Error;
pub type NfaCompileResult<T> = Result<T, NfaCompileError>;
#[derive(Error, Debug, Clone)]
pub enum NfaCompileError {
#[error("unresolved group reference: {name}")]
UnresolvedGroupRef {
name: String,
location: Option<SourceRef>,
},
#[error("unresolved element reference: {name}")]
UnresolvedElementRef {
name: String,
location: Option<SourceRef>,
},
#[error("invalid occurrence: minOccurs ({min}) > maxOccurs ({max})")]
InvalidOccurrence {
min: u32,
max: u32,
location: Option<SourceRef>,
},
#[error("xs:all group can only contain element particles in XSD 1.0")]
InvalidAllGroupContent { location: Option<SourceRef> },
#[error("invalid xs:all occurrence constraint: {reason}")]
InvalidAllGroupOccurs {
reason: String,
location: Option<SourceRef>,
},
#[error("recursion limit exceeded while compiling content model")]
RecursionLimitExceeded { location: Option<SourceRef> },
#[error("empty content model")]
EmptyContentModel { location: Option<SourceRef> },
}
impl NfaCompileError {
pub fn unresolved_group(name: impl Into<String>, location: Option<SourceRef>) -> Self {
NfaCompileError::UnresolvedGroupRef {
name: name.into(),
location,
}
}
pub fn unresolved_element(name: impl Into<String>, location: Option<SourceRef>) -> Self {
NfaCompileError::UnresolvedElementRef {
name: name.into(),
location,
}
}
pub fn invalid_occurrence(min: u32, max: u32, location: Option<SourceRef>) -> Self {
NfaCompileError::InvalidOccurrence { min, max, location }
}
pub fn invalid_all_group(location: Option<SourceRef>) -> Self {
NfaCompileError::InvalidAllGroupContent { location }
}
pub fn invalid_all_group_occurs(
reason: impl Into<String>,
location: Option<SourceRef>,
) -> Self {
NfaCompileError::InvalidAllGroupOccurs {
reason: reason.into(),
location,
}
}
pub fn recursion_exceeded(location: Option<SourceRef>) -> Self {
NfaCompileError::RecursionLimitExceeded { location }
}
pub fn empty_content(location: Option<SourceRef>) -> Self {
NfaCompileError::EmptyContentModel { location }
}
pub fn location(&self) -> Option<&SourceRef> {
match self {
NfaCompileError::UnresolvedGroupRef { location, .. } => location.as_ref(),
NfaCompileError::UnresolvedElementRef { location, .. } => location.as_ref(),
NfaCompileError::InvalidOccurrence { location, .. } => location.as_ref(),
NfaCompileError::InvalidAllGroupContent { location } => location.as_ref(),
NfaCompileError::InvalidAllGroupOccurs { location, .. } => location.as_ref(),
NfaCompileError::RecursionLimitExceeded { location } => location.as_ref(),
NfaCompileError::EmptyContentModel { location } => location.as_ref(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_messages() {
let err = NfaCompileError::unresolved_group("myGroup", None);
assert!(err.to_string().contains("myGroup"));
let err = NfaCompileError::invalid_occurrence(5, 3, None);
assert!(err.to_string().contains("5"));
assert!(err.to_string().contains("3"));
}
#[test]
fn test_location_accessor() {
let err = NfaCompileError::unresolved_element("elem", None);
assert!(err.location().is_none());
}
}