use serde::Serialize;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
El(#[from] ontologos_el::Error),
#[error(transparent)]
Dl(#[from] ontologos_dl::Error),
#[error(transparent)]
Rl(#[from] ontologos_rl::Error),
#[error(transparent)]
Swrl(#[from] ontologos_swrl::Error),
#[error(transparent)]
Core(#[from] ontologos_core::Error),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(untagged)]
pub enum EntailmentCheck {
SubClassOf {
sub: String,
sup: String,
},
ClassAssertion {
individual: String,
class: String,
},
ObjectPropertyAssertion {
subject: String,
property: String,
object: String,
},
}
pub fn parse_entailment_check(
sub: Option<String>,
sup: Option<String>,
individual: Option<String>,
class: Option<String>,
subject: Option<String>,
property: Option<String>,
object: Option<String>,
) -> Result<EntailmentCheck> {
let subclass = sub.is_some() || sup.is_some();
let class_assertion = individual.is_some() || class.is_some();
let property_assertion = subject.is_some() || property.is_some() || object.is_some();
let count =
usize::from(subclass) + usize::from(class_assertion) + usize::from(property_assertion);
if count != 1 {
return Err(Error::Core(ontologos_core::Error::Message(
"entail requires exactly one of: (--sub and --sup), (--individual and --class), or (--subject, --property, and --object)".into(),
)));
}
if subclass {
let sub = sub
.ok_or_else(|| Error::Core(ontologos_core::Error::Message("--sub required".into())))?;
let sup = sup
.ok_or_else(|| Error::Core(ontologos_core::Error::Message("--sup required".into())))?;
return Ok(EntailmentCheck::SubClassOf { sub, sup });
}
if class_assertion {
let individual = individual.ok_or_else(|| {
Error::Core(ontologos_core::Error::Message(
"--individual required".into(),
))
})?;
let class = class.ok_or_else(|| {
Error::Core(ontologos_core::Error::Message("--class required".into()))
})?;
return Ok(EntailmentCheck::ClassAssertion { individual, class });
}
let subject = subject
.ok_or_else(|| Error::Core(ontologos_core::Error::Message("--subject required".into())))?;
let property = property
.ok_or_else(|| Error::Core(ontologos_core::Error::Message("--property required".into())))?;
let object = object
.ok_or_else(|| Error::Core(ontologos_core::Error::Message("--object required".into())))?;
Ok(EntailmentCheck::ObjectPropertyAssertion {
subject,
property,
object,
})
}