use iri_rfc3987::Iri;
use crate::{Annotation, Axiom, OntologyId, StructuralModelError};
const KIND_ONTOLOGY_PATCH: &str = "ontology patch";
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(
try_from = "OntologyPatchInput<L, B>",
bound(deserialize = "L: serde::Deserialize<'de>, B: serde::Deserialize<'de>")
)]
pub struct OntologyPatch<L = crate::OwlLiteral, B = crate::BlankNodeId> {
target: OntologyId,
operations: Vec<OntologyPatchOperation<L, B>>,
}
impl<L, B> OntologyPatch<L, B> {
pub fn try_new(
target: OntologyId,
operations: Vec<OntologyPatchOperation<L, B>>,
) -> Result<Self, StructuralModelError> {
if operations.is_empty() {
return Err(StructuralModelError::InvalidFormat {
kind: KIND_ONTOLOGY_PATCH,
value: "0 operations".to_owned(),
message: "requires at least one operation",
});
}
Ok(Self { target, operations })
}
#[must_use]
pub fn target(&self) -> &OntologyId {
&self.target
}
#[must_use]
pub fn operations(&self) -> &[OntologyPatchOperation<L, B>] {
&self.operations
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub enum OntologyPatchOperation<L = crate::OwlLiteral, B = crate::BlankNodeId> {
AddImport {
import_iri: Iri<String>,
},
RemoveImport {
import_iri: Iri<String>,
},
AddAnnotation {
annotation: Annotation<L, B>,
},
RemoveAnnotation {
annotation: Annotation<L, B>,
},
AddAxiom {
axiom: Axiom<L, B>,
},
RemoveAxiom {
axiom: Axiom<L, B>,
},
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename = "OntologyPatch<L, B>")]
struct OntologyPatchInput<L, B> {
target: OntologyId,
operations: Vec<OntologyPatchOperation<L, B>>,
}
impl<L, B> TryFrom<OntologyPatchInput<L, B>> for OntologyPatch<L, B> {
type Error = StructuralModelError;
fn try_from(input: OntologyPatchInput<L, B>) -> Result<Self, Self::Error> {
Self::try_new(input.target, input.operations)
}
}