From b3124728d61642e389873db2fbf7427e29e0fd70 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Tue, 2 Jul 2024 11:24:37 +0100 Subject: [PATCH] Update OFN reader to a generic return type --- .pre-commit-config.yaml | 4 +- src/io/ofn/reader/from_pair.rs | 118 ++++++++++++++++--------------- src/io/ofn/reader/mod.rs | 17 +++-- src/io/ofn/writer/mod.rs | 7 +- src/model.rs | 2 +- src/ontology/component_mapped.rs | 2 + 6 files changed, 79 insertions(+), 71 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 281ddb6..385e8f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,9 +16,9 @@ repos: pass_filenames: false stages: [pre-commit, pre-push] - id: Compile Benches - name: Running Test + name: Compile Benches language: system - entry: cargo bench --no-run + entry: cargo bench --no-run --quiet pass_filenames: false stages: [pre-commit, pre-push] - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/src/io/ofn/reader/from_pair.rs b/src/io/ofn/reader/from_pair.rs index ec737ed..a066ccf 100644 --- a/src/io/ofn/reader/from_pair.rs +++ b/src/io/ofn/reader/from_pair.rs @@ -1,4 +1,5 @@ use std::collections::BTreeSet; +use std::marker::PhantomData; use std::str::FromStr; use curie::Curie; @@ -8,7 +9,6 @@ use pest::iterators::Pair; use crate::error::HornedError; use crate::model::*; -use crate::ontology::set::SetOntology; use crate::vocab::{Facet, OWL2Datatype, OWL}; use super::Context; @@ -941,63 +941,62 @@ impl FromPair for ObjectPropertyExpression { } // --------------------------------------------------------------------------- +pub(crate) struct MutableOntologyWrapper + Ontology + Default>( + pub(crate) O, + PhantomData, +); -macro_rules! impl_ontology { - ($ty:ident) => { - impl FromPair for $ty { - const RULE: Rule = Rule::Ontology; - fn from_pair_unchecked(pair: Pair, ctx: &Context<'_, A>) -> Result { - debug_assert!(pair.as_rule() == Rule::Ontology); - let mut pairs = pair.into_inner(); - let mut pair = pairs.next().unwrap(); - - let mut ontology = $ty::default(); - let mut ontology_id = OntologyID::default(); - - // Parse ontology IRI and Version IRI if any - if pair.as_rule() == Rule::OntologyIRI { - let inner = pair.into_inner().next().unwrap(); - ontology_id.iri = Some(IRI::from_pair(inner, ctx)?); - pair = pairs.next().unwrap(); - if pair.as_rule() == Rule::VersionIRI { - let inner = pair.into_inner().next().unwrap(); - ontology_id.viri = Some(IRI::from_pair(inner, ctx)?); - pair = pairs.next().unwrap(); - } - } - ontology.insert(ontology_id); +impl + Ontology + Default> FromPair + for MutableOntologyWrapper +{ + const RULE: Rule = Rule::Ontology; + fn from_pair_unchecked(pair: Pair, ctx: &Context<'_, A>) -> Result { + debug_assert!(pair.as_rule() == Rule::Ontology); + let mut pairs = pair.into_inner(); + let mut pair = pairs.next().unwrap(); - // Process imports - for p in pair.into_inner() { - ontology.insert(Import::from_pair(p, ctx)?); - } + let mut ontology: O = Default::default(); + let mut ontology_id = OntologyID::default(); - // Process ontology annotations - for pair in pairs.next().unwrap().into_inner() { - ontology.insert(OntologyAnnotation::from_pair(pair, ctx)?); - } + // Parse ontology IRI and Version IRI if any + if pair.as_rule() == Rule::OntologyIRI { + let inner = pair.into_inner().next().unwrap(); + ontology_id.iri = Some(IRI::from_pair(inner, ctx)?); + pair = pairs.next().unwrap(); + if pair.as_rule() == Rule::VersionIRI { + let inner = pair.into_inner().next().unwrap(); + ontology_id.viri = Some(IRI::from_pair(inner, ctx)?); + pair = pairs.next().unwrap(); + } + } + ontology.insert(ontology_id); - // Process axioms, ignore SWRL rules - for pair in pairs.next().unwrap().into_inner() { - let inner = pair.into_inner().next().unwrap(); - match inner.as_rule() { - Rule::Axiom => { - ontology.insert(AnnotatedComponent::from_pair(inner, ctx)?); - } - rule => { - unreachable!("unexpected rule in Ontology::from_pair: {:?}", rule); - } - } - } + // Process imports + for p in pair.into_inner() { + ontology.insert(Import::from_pair(p, ctx)?); + } + + // Process ontology annotations + for pair in pairs.next().unwrap().into_inner() { + ontology.insert(OntologyAnnotation::from_pair(pair, ctx)?); + } - Ok(ontology) + // Process axioms, ignore SWRL rules + for pair in pairs.next().unwrap().into_inner() { + let inner = pair.into_inner().next().unwrap(); + match inner.as_rule() { + Rule::Axiom => { + ontology.insert(AnnotatedComponent::from_pair(inner, ctx)?); + } + rule => { + unreachable!("unexpected rule in Ontology::from_pair: {:?}", rule); + } } } - }; -} -impl_ontology!(SetOntology); -// impl_ontology!(AxiomMappedOntology); + Ok(MutableOntologyWrapper(ontology, Default::default())) + } +} // --------------------------------------------------------------------------- @@ -1035,17 +1034,18 @@ impl FromPair for PrefixMapping { // --------------------------------------------------------------------------- -impl FromPair for (O, PrefixMapping) +impl FromPair for (MutableOntologyWrapper, PrefixMapping) where A: ForIRI, - O: Ontology + FromPair, + O: Default + MutableOntology + Ontology, { const RULE: Rule = Rule::OntologyDocument; fn from_pair_unchecked(pair: Pair, ctx: &Context<'_, A>) -> Result { let mut pairs = pair.into_inner(); let prefixes = PrefixMapping::from_pair(pairs.next().unwrap(), ctx)?; let context = Context::new(ctx.build, &prefixes); - O::from_pair(pairs.next().unwrap(), &context).map(|ont| (ont, prefixes)) + MutableOntologyWrapper::from_pair(pairs.next().unwrap(), &context) + .map(|ont| (ont, prefixes)) } } @@ -1117,6 +1117,7 @@ mod tests { use super::*; use crate::io::ofn::reader::lexer::OwlFunctionalLexer; + use crate::ontology::set::SetOntology; use test_generator::test_resources; @@ -1244,8 +1245,10 @@ mod tests { .next() .unwrap(); - let doc: (SetOntology, PrefixMapping) = - FromPair::from_pair(pair, &Context::new(&build, &prefixes)).unwrap(); + let doc: ( + MutableOntologyWrapper<_, SetOntology>, + PrefixMapping, + ) = FromPair::from_pair(pair, &Context::new(&build, &prefixes)).unwrap(); assert_eq!( doc.1.mappings().collect::>(), expected.mappings().collect::>() @@ -1291,7 +1294,8 @@ mod tests { let build = Build::new(); let prefixes = PrefixMapping::default(); let ctx = Context::new(&build, &prefixes); - let item: (SetOntology>, _) = FromPair::from_pair(pair, &ctx).unwrap(); + let item: (MutableOntologyWrapper<_, SetOntology>>, _) = + FromPair::from_pair(pair, &ctx).unwrap(); let path = resource .replace("owl-functional", "owl-xml") @@ -1301,6 +1305,6 @@ mod tests { crate::io::owx::reader::read(&mut Cursor::new(&owx), Default::default()).unwrap(); // pretty_assertions::assert_eq!(item.1, expected.1); - pretty_assertions::assert_eq!(item.0, expected.0); + pretty_assertions::assert_eq!(item.0 .0, expected.0); } } diff --git a/src/io/ofn/reader/mod.rs b/src/io/ofn/reader/mod.rs index 3b9a933..96e6382 100644 --- a/src/io/ofn/reader/mod.rs +++ b/src/io/ofn/reader/mod.rs @@ -6,13 +6,14 @@ use crate::error::HornedError; use crate::io::ParserConfiguration; use crate::model::Build; use crate::model::ForIRI; -use crate::model::RcStr; -use crate::ontology::set::SetOntology; +use crate::model::MutableOntology; +use crate::model::Ontology; mod from_pair; mod lexer; use self::from_pair::FromPair; +use self::from_pair::MutableOntologyWrapper; use self::lexer::OwlFunctionalLexer; use self::lexer::Rule; @@ -27,18 +28,18 @@ impl<'a, A: ForIRI> Context<'a, A> { } } -pub fn read( +pub fn read + Ontology + Default, R: BufRead>( bufread: R, _config: ParserConfiguration, -) -> Result<(SetOntology, PrefixMapping), HornedError> { +) -> Result<(O, PrefixMapping), HornedError> { let b = Build::new(); read_with_build(bufread, &b) } -pub fn read_with_build( +pub fn read_with_build + Ontology + Default, R: BufRead>( mut bufread: R, build: &Build, -) -> Result<(SetOntology, PrefixMapping), HornedError> { +) -> Result<(O, PrefixMapping), HornedError> { let prefixes = PrefixMapping::default(); let ctx = Context::new(build, &prefixes); @@ -49,5 +50,7 @@ pub fn read_with_build( .next() .unwrap(); - FromPair::from_pair(pair, &ctx) + let wrapper: Result<(MutableOntologyWrapper, PrefixMapping), HornedError> = + FromPair::from_pair(pair, &ctx); + wrapper.map(|r| (r.0 .0, r.1)) } diff --git a/src/io/ofn/writer/mod.rs b/src/io/ofn/writer/mod.rs index b489f9e..82e5b00 100644 --- a/src/io/ofn/writer/mod.rs +++ b/src/io/ofn/writer/mod.rs @@ -104,12 +104,11 @@ mod test { let reader = std::fs::File::open(&resource) .map(std::io::BufReader::new) .unwrap(); - let (ont, prefixes) = crate::io::ofn::reader::read(reader, Default::default()).unwrap(); + let (ont, prefixes): (ComponentMappedOntology>, _) = + crate::io::ofn::reader::read(reader, Default::default()).unwrap(); - let component_mapped: ComponentMappedOntology> = - ont.clone().into(); let mut writer = Vec::new(); - crate::io::ofn::writer::write(&mut writer, &component_mapped, Some(&prefixes)).unwrap(); + crate::io::ofn::writer::write(&mut writer, &ont, Some(&prefixes)).unwrap(); let (ont2, prefixes2) = crate::io::ofn::reader::read(std::io::Cursor::new(&writer), Default::default()) diff --git a/src/model.rs b/src/model.rs index b655baa..348bbc2 100644 --- a/src/model.rs +++ b/src/model.rs @@ -2044,7 +2044,7 @@ pub enum DArgument { pub trait Ontology {} /// Add or remove axioms to an `MutableOntology` -pub trait MutableOntology { +pub trait MutableOntology: Ontology { /// Insert an axiom into the ontology. /// /// # Examples diff --git a/src/ontology/component_mapped.rs b/src/ontology/component_mapped.rs index a7b2e9a..1043ed4 100644 --- a/src/ontology/component_mapped.rs +++ b/src/ontology/component_mapped.rs @@ -292,6 +292,8 @@ impl> Default for ComponentMappedOntology { } } +impl> Ontology for ComponentMappedOntology {} + impl> MutableOntology for ComponentMappedOntology { fn insert(&mut self, cmp: IAA) -> bool where