use std::borrow::Cow;
use crate::{BlankId, CowId, CowLiteral, CowLocalTerm, CowTerm, IdRef, LiteralRef, LocalTermRef, TermRef, TripleTerm};
pub type TripleTermView<'a, R> = (Cow<'a, R>, Cow<'a, R>, Cow<'a, R>);
mod r#impl;
pub use r#impl::*;
pub mod fallible;
pub use fallible::FallibleInterpretation;
mod iri;
pub use iri::*;
mod blank_id;
pub use blank_id::*;
mod literal;
pub use literal::*;
mod id;
pub use id::*;
mod term;
pub use term::*;
use iri_rs::{Iri, IriBuf};
pub trait Interpretation {
type Resource;
fn iri(&self, iri: Iri<&str>) -> Option<Self::Resource>;
fn literal<'a>(&self, literal: impl Into<LiteralRef<'a>>) -> Option<Self::Resource>;
fn term<'a>(&self, term: impl Into<TermRef<'a>>) -> Option<Self::Resource> {
match term.into() {
TermRef::Iri(iri) => self.iri(iri),
TermRef::Literal(l) => self.literal(l),
}
}
}
impl<I: Interpretation> Interpretation for &I {
type Resource = I::Resource;
fn iri(&self, iri: Iri<&str>) -> Option<Self::Resource> {
I::iri(*self, iri)
}
fn literal<'a>(&self, literal: impl Into<LiteralRef<'a>>) -> Option<Self::Resource> {
I::literal(*self, literal)
}
}
impl<I: Interpretation> Interpretation for &mut I {
type Resource = I::Resource;
fn iri(&self, iri: Iri<&str>) -> Option<Self::Resource> {
I::iri(*self, iri)
}
fn literal<'a>(&self, literal: impl Into<LiteralRef<'a>>) -> Option<Self::Resource> {
I::literal(*self, literal)
}
}
pub trait TraversableInterpretation: Interpretation {
type Resources<'a>: Iterator<Item = &'a Self::Resource>
where
Self: 'a;
fn resources(&self) -> Self::Resources<'_>;
}
pub trait GenerativeInterpretation: Interpretation {
fn new_resource(&mut self) -> Self::Resource;
}
pub trait ConstGenerativeInterpretation: Interpretation {
fn new_resource(&self) -> Self::Resource;
}
impl<I: ConstGenerativeInterpretation> GenerativeInterpretation for I {
fn new_resource(&mut self) -> Self::Resource {
ConstGenerativeInterpretation::new_resource(self)
}
}
pub trait InterpretationMut: Interpretation {
fn insert_iri<'a>(&mut self, iri: impl Into<Cow<'a, IriBuf>>) -> Self::Resource;
fn insert_literal<'a>(&mut self, literal: impl Into<CowLiteral<'a>>) -> Self::Resource;
fn insert_term<'a>(&mut self, term: impl Into<CowTerm<'a>>) -> Self::Resource {
match term.into() {
CowTerm::Iri(iri) => self.insert_iri(iri),
CowTerm::Literal(literal) => self.insert_literal(literal),
}
}
}
pub trait ReverseInterpretation: Interpretation {
type Iris<'a>: Iterator<Item = Cow<'a, IriBuf>>
where
Self: 'a;
type Literals<'a>: Iterator<Item = CowLiteral<'a>>
where
Self: 'a;
fn iris_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::Iris<'a>;
fn literals_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::Literals<'a>;
fn terms_of<'a>(&'a self, resource: &'a Self::Resource) -> TermsOf<'a, Self> {
TermsOf {
iris: self.iris_of(resource),
literals: self.literals_of(resource),
}
}
fn triple_term_components(&self, _resource: &Self::Resource) -> Option<(Self::Resource, Self::Resource, Self::Resource)> {
None
}
fn triple_term_components_view<'a>(&'a self, resource: &'a Self::Resource) -> Option<TripleTermView<'a, Self::Resource>>
where
Self::Resource: Clone,
{
self.triple_term_components(resource)
.map(|(s, p, o)| (Cow::Owned(s), Cow::Owned(p), Cow::Owned(o)))
}
fn is_blank_id(&self, resource: &Self::Resource) -> bool {
self.terms_of(resource).next().is_none() && self.triple_term_components(resource).is_none()
}
}
pub struct TermsOf<'a, I: 'a + ?Sized + ReverseInterpretation> {
iris: I::Iris<'a>,
literals: I::Literals<'a>,
}
impl<'a, I: 'a + ?Sized + ReverseInterpretation> Iterator for TermsOf<'a, I> {
type Item = CowTerm<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iris.next().map(CowTerm::Iri).or_else(|| self.literals.next().map(CowTerm::Literal))
}
}
pub trait LocalInterpretation: Interpretation {
fn blank_id(&self, blank_id: &BlankId) -> Option<Self::Resource>;
fn local_term<'a>(&self, term: impl Into<LocalTermRef<'a>>) -> Option<Self::Resource> {
match term.into() {
LocalTermRef::BlankId(blank_id) => self.blank_id(blank_id),
LocalTermRef::Named(term) => self.term(term),
LocalTermRef::Triple(t) => self.triple_term(t.clone()),
}
}
fn triple_term(&self, _t: TripleTerm) -> Option<Self::Resource> {
None
}
fn id<'a>(&self, id: impl Into<IdRef<'a>>) -> Option<Self::Resource> {
match id.into() {
IdRef::BlankId(blank_id) => self.blank_id(blank_id),
IdRef::Iri(iri) => self.iri(iri),
}
}
}
pub trait LocalInterpretationMut: InterpretationMut {
fn insert_blank_id<'a>(&mut self, blank_id: impl Into<Cow<'a, BlankId>>) -> Self::Resource;
fn insert_local_term<'a>(&mut self, term: impl Into<CowLocalTerm<'a>>) -> Self::Resource {
match term.into() {
CowLocalTerm::BlankId(blank_id) => self.insert_blank_id(blank_id),
CowLocalTerm::Named(term) => self.insert_term(term),
CowLocalTerm::Triple(t) => self.insert_triple_term(t.into_owned()),
}
}
fn insert_triple_term(&mut self, _t: TripleTerm) -> Self::Resource {
unimplemented!("triple-term insertion not implemented by this LocalInterpretationMut")
}
fn insert_id<'a>(&mut self, term: impl Into<CowId<'a>>) -> Self::Resource {
match term.into() {
CowId::BlankId(blank_id) => self.insert_blank_id(blank_id),
CowId::Iri(iri) => self.insert_iri(iri),
}
}
}
pub trait ReverseLocalInterpretation: ReverseInterpretation {
type BlankIds<'a>: Iterator<Item = Cow<'a, BlankId>>
where
Self: 'a;
fn blank_ids_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::BlankIds<'a>;
fn local_terms_of<'a>(&'a self, resource: &'a Self::Resource) -> LocalTermsOf<'a, Self> {
LocalTermsOf {
terms: self.terms_of(resource),
blank_ids: self.blank_ids_of(resource),
}
}
}
pub struct LocalTermsOf<'a, I: 'a + ?Sized + ReverseLocalInterpretation> {
terms: TermsOf<'a, I>,
blank_ids: I::BlankIds<'a>,
}
impl<'a, I: 'a + ?Sized + ReverseLocalInterpretation> Iterator for LocalTermsOf<'a, I> {
type Item = CowLocalTerm<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.terms
.next()
.map(CowLocalTerm::Named)
.or_else(|| self.blank_ids.next().map(CowLocalTerm::BlankId))
}
}