use crate::{
BlankIdBuf, GraphLabel, IriVocabularyMut, Quad, StringLiteral, Subject, Triple, VocabularyMut,
};
use iref::IriBuf;
use langtag::LanguageTagBuf;
use locspan::{Meta, Strip};
use locspan_derive::*;
use std::fmt;
#[cfg(feature = "contextual")]
use contextual::DisplayWithContext;
pub type Term<M, I = IriBuf, B = BlankIdBuf, S = StringLiteral, L = LanguageTagBuf> =
crate::Term<I, B, Literal<M, S, I, L>>;
pub type Object<M, I = IriBuf, B = BlankIdBuf, S = StringLiteral, L = LanguageTagBuf> =
crate::Object<I, B, Literal<M, S, I, L>>;
pub type MetaTerm<M, I = IriBuf, B = BlankIdBuf, S = StringLiteral, L = LanguageTagBuf> =
Meta<Term<M, I, B, S, L>, M>;
pub type MetaObject<M, I = IriBuf, B = BlankIdBuf, S = StringLiteral, L = LanguageTagBuf> =
Meta<Object<M, I, B, S, L>, M>;
pub type MetaQuad<S, P, O, G, M> = Meta<Quad<Meta<S, M>, Meta<P, M>, Meta<O, M>, Meta<G, M>>, M>;
pub type MetaRdfQuad<M> =
Meta<Quad<Meta<Subject, M>, Meta<IriBuf, M>, MetaObject<M>, Meta<GraphLabel, M>>, M>;
pub type MetaGrdfQuad<M> = Meta<Quad<MetaTerm<M>, MetaTerm<M>, MetaTerm<M>, MetaTerm<M>>, M>;
impl<I, B> Strip for Subject<I, B> {
type Stripped = Self;
fn strip(self) -> Self {
self
}
}
#[derive(
Clone,
PartialEq,
Eq,
Hash,
PartialOrd,
Ord,
Debug,
StrippedPartialEq,
StrippedEq,
StrippedPartialOrd,
StrippedOrd,
StrippedHash,
)]
#[locspan(ignore(M))]
#[locspan(stripped(S, I, L))]
pub enum Literal<M, S = StringLiteral, I = IriBuf, L = LanguageTagBuf> {
String(#[locspan(deref_stripped)] Meta<S, M>),
TypedString(
#[locspan(deref_stripped)] Meta<S, M>,
#[locspan(deref_stripped)] Meta<I, M>,
),
LangString(
#[locspan(deref_stripped)] Meta<S, M>,
#[locspan(deref_stripped)] Meta<L, M>,
),
}
impl<M, S, I, L> Literal<M, S, I, L> {
pub fn is_typed(&self) -> bool {
matches!(self, Self::TypedString(_, _))
}
pub fn ty(&self) -> Option<&Meta<I, M>> {
match self {
Self::TypedString(_, ty) => Some(ty),
_ => None,
}
}
pub fn is_lang_string(&self) -> bool {
matches!(self, Self::LangString(_, _))
}
pub fn lang_tag(&self) -> Option<&Meta<L, M>> {
match self {
Self::LangString(_, tag) => Some(tag),
_ => None,
}
}
pub fn string_literal(&self) -> &Meta<S, M> {
match self {
Self::String(s) => s,
Self::TypedString(s, _) => s,
Self::LangString(s, _) => s,
}
}
pub fn into_string_literal(self) -> Meta<S, M> {
match self {
Self::String(s) => s,
Self::TypedString(s, _) => s,
Self::LangString(s, _) => s,
}
}
pub fn strip(self) -> super::Literal<S, I, L> {
match self {
Self::String(Meta(lit, _)) => super::Literal::String(lit),
Self::TypedString(Meta(lit, _), Meta(iri_ref, _)) => {
super::Literal::TypedString(lit, iri_ref)
}
Self::LangString(Meta(lit, _), Meta(tag, _)) => super::Literal::LangString(lit, tag),
}
}
}
impl<M, S, I, L> Strip for Literal<M, S, I, L> {
type Stripped = super::Literal<S, I, L>;
fn strip(self) -> Self::Stripped {
self.strip()
}
}
impl<M, S: fmt::Display, I: fmt::Display, L: fmt::Display> fmt::Display for Literal<M, S, I, L> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::String(s) => s.value().fmt(f),
Self::TypedString(s, ty) => write!(f, "{}^^<{}>", s.value(), ty.value()),
Self::LangString(s, tag) => write!(f, "{}@{}", s.value(), tag.value()),
}
}
}
#[cfg(feature = "contextual")]
impl<M, S: fmt::Display, I, L: fmt::Display, V: crate::IriVocabulary<Iri = I>> DisplayWithContext<V>
for Literal<M, S, I, L>
{
fn fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::String(s) => s.value().fmt(f),
Self::TypedString(s, ty) => write!(
f,
"{}^^<{}>",
s.value(),
vocabulary.iri(ty.value()).unwrap()
),
Self::LangString(s, tag) => write!(f, "{}@{}", s.value(), tag.value()),
}
}
}
impl<I, B, L: Strip> super::Term<I, B, L> {
pub fn strip(self) -> super::Term<I, B, L::Stripped> {
match self {
Self::Blank(id) => super::Term::Blank(id),
Self::Iri(iri) => super::Term::Iri(iri),
Self::Literal(lit) => super::Term::Literal(lit.strip()),
}
}
}
impl<I, B, L: Strip> Strip for super::Term<I, B, L> {
type Stripped = super::Term<I, B, L::Stripped>;
fn strip(self) -> Self::Stripped {
self.strip()
}
}
impl<S: Strip, P: Strip, O: Strip> Strip for Triple<S, P, O> {
type Stripped = Triple<S::Stripped, P::Stripped, O::Stripped>;
fn strip(self) -> Self::Stripped {
Triple(self.0.strip(), self.1.strip(), self.2.strip())
}
}
impl<S: Strip, P: Strip, O: Strip, G: Strip> Strip for Quad<S, P, O, G> {
type Stripped = Quad<S::Stripped, P::Stripped, O::Stripped, G::Stripped>;
fn strip(self) -> Self::Stripped {
Quad(
self.0.strip(),
self.1.strip(),
self.2.strip(),
self.3.strip(),
)
}
}
impl<S: Strip, P, O: Strip, G: Strip, M> Quad<S, Meta<P, M>, O, G> {
pub fn strip_all_but_predicate(self) -> Quad<S::Stripped, P, O::Stripped, G::Stripped> {
Quad(
self.0.strip(),
self.1.into_value(),
self.2.strip(),
self.3.strip(),
)
}
}
impl<S, L, M> Literal<M, S, IriBuf, L> {
pub fn inserted_into<V: IriVocabularyMut>(&self, vocabulary: &mut V) -> Literal<M, S, V::Iri, L>
where
S: Clone,
L: Clone,
M: Clone,
{
match self {
Self::String(s) => Literal::String(s.clone()),
Self::TypedString(s, Meta(t, m)) => {
Literal::TypedString(s.clone(), Meta(vocabulary.insert(t.as_iri()), m.clone()))
}
Self::LangString(s, l) => Literal::LangString(s.clone(), l.clone()),
}
}
pub fn insert_into<V: IriVocabularyMut>(self, vocabulary: &mut V) -> Literal<M, S, V::Iri, L> {
match self {
Self::String(s) => Literal::String(s),
Self::TypedString(s, Meta(t, m)) => {
Literal::TypedString(s, Meta(vocabulary.insert(t.as_iri()), m))
}
Self::LangString(s, l) => Literal::LangString(s, l),
}
}
}
impl<S, L, M> Term<M, IriBuf, BlankIdBuf, S, L> {
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Term<M, V::Iri, V::BlankId, S, L>
where
S: Clone,
L: Clone,
M: Clone,
{
match self {
Self::Blank(b) => Term::Blank(vocabulary.insert_blank_id(b.as_blank_id_ref())),
Self::Iri(i) => Term::Iri(vocabulary.insert(i.as_iri())),
Self::Literal(l) => Term::Literal(l.inserted_into(vocabulary)),
}
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Term<M, V::Iri, V::BlankId, S, L> {
match self {
Self::Blank(b) => Term::Blank(vocabulary.insert_blank_id(b.as_blank_id_ref())),
Self::Iri(i) => Term::Iri(vocabulary.insert(i.as_iri())),
Self::Literal(l) => Term::Literal(l.insert_into(vocabulary)),
}
}
}
impl<S, L, M>
Triple<Meta<Subject, M>, Meta<IriBuf, M>, Meta<Object<M, IriBuf, BlankIdBuf, S, L>, M>>
{
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Triple<
Meta<Subject<V::Iri, V::BlankId>, M>,
Meta<V::Iri, M>,
Meta<Object<M, V::Iri, V::BlankId, S, L>, M>,
>
where
S: Clone,
L: Clone,
M: Clone,
{
Triple(
Meta(self.0.inserted_into(vocabulary), self.0.metadata().clone()),
Meta(
vocabulary.insert(self.1.as_iri()),
self.1.metadata().clone(),
),
Meta(self.2.inserted_into(vocabulary), self.2.metadata().clone()),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Triple<
Meta<Subject<V::Iri, V::BlankId>, M>,
Meta<V::Iri, M>,
Meta<Object<M, V::Iri, V::BlankId, S, L>, M>,
> {
Triple(
self.0.map(|s| s.insert_into(vocabulary)),
self.1.map(|p| vocabulary.insert(p.as_iri())),
self.2.map(|o| o.insert_into(vocabulary)),
)
}
}
impl<S, L, M>
Triple<
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
>
{
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Triple<
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
>
where
S: Clone,
L: Clone,
M: Clone,
{
Triple(
Meta(self.0.inserted_into(vocabulary), self.0.metadata().clone()),
Meta(self.1.inserted_into(vocabulary), self.1.metadata().clone()),
Meta(self.2.inserted_into(vocabulary), self.2.metadata().clone()),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Triple<
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
> {
Triple(
self.0.map(|s| s.insert_into(vocabulary)),
self.1.map(|p| p.insert_into(vocabulary)),
self.2.map(|o| o.insert_into(vocabulary)),
)
}
}
impl<S, L, M>
Quad<
Meta<Subject, M>,
Meta<IriBuf, M>,
Meta<Object<M, IriBuf, BlankIdBuf, S, L>, M>,
Meta<GraphLabel, M>,
>
{
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Quad<
Meta<Subject<V::Iri, V::BlankId>, M>,
Meta<V::Iri, M>,
Meta<Object<M, V::Iri, V::BlankId, S, L>, M>,
Meta<GraphLabel<V::Iri, V::BlankId>, M>,
>
where
S: Clone,
L: Clone,
M: Clone,
{
Quad(
Meta(self.0.inserted_into(vocabulary), self.0.metadata().clone()),
Meta(
vocabulary.insert(self.1.as_iri()),
self.1.metadata().clone(),
),
Meta(self.2.inserted_into(vocabulary), self.2.metadata().clone()),
self.3
.as_ref()
.map(|Meta(g, m)| Meta(g.inserted_into(vocabulary), m.clone())),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Quad<
Meta<Subject<V::Iri, V::BlankId>, M>,
Meta<V::Iri, M>,
Meta<Object<M, V::Iri, V::BlankId, S, L>, M>,
Meta<GraphLabel<V::Iri, V::BlankId>, M>,
> {
Quad(
self.0.map(|s| s.insert_into(vocabulary)),
self.1.map(|p| vocabulary.insert(p.as_iri())),
self.2.map(|o| o.insert_into(vocabulary)),
self.3.map(|Meta(g, m)| Meta(g.insert_into(vocabulary), m)),
)
}
}
impl<S, L, M>
Quad<
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
Meta<Term<M, IriBuf, BlankIdBuf, S, L>, M>,
>
{
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Quad<
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
>
where
S: Clone,
L: Clone,
M: Clone,
{
Quad(
Meta(self.0.inserted_into(vocabulary), self.0.metadata().clone()),
Meta(self.1.inserted_into(vocabulary), self.1.metadata().clone()),
Meta(self.2.inserted_into(vocabulary), self.2.metadata().clone()),
self.3
.as_ref()
.map(|Meta(g, m)| Meta(g.inserted_into(vocabulary), m.clone())),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Quad<
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
Meta<Term<M, V::Iri, V::BlankId, S, L>, M>,
> {
Quad(
self.0.map(|s| s.insert_into(vocabulary)),
self.1.map(|p| p.insert_into(vocabulary)),
self.2.map(|o| o.insert_into(vocabulary)),
self.3.map(|Meta(g, m)| Meta(g.insert_into(vocabulary), m)),
)
}
}