use crate::{BlankIdBuf, Datatype, Id, IsGraph, IsObject, IsPredicate, IsSubject, Literal, LiteralType, LocalTerm, Quad, Resource, Term, Triple};
use iri_rs::IriBuf;
#[doc(no_inline)]
pub use locspan::{Location, Span};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Meta<T, M>(pub T, pub M);
impl<T: crate::__seal::Sealed, M> crate::__seal::Sealed for Meta<T, M> {}
impl<T: IsSubject, M> IsSubject for Meta<T, M> {}
impl<T: IsPredicate, M> IsPredicate for Meta<T, M> {}
impl<T: IsObject, M> IsObject for Meta<T, M> {}
impl<T: IsGraph, M> IsGraph for Meta<T, M> {}
impl<T: Resource, M> Resource for Meta<T, M> {}
impl<T, M> Meta<T, M> {
pub const fn new(value: T, metadata: M) -> Self {
Self(value, metadata)
}
pub const fn value(&self) -> &T {
&self.0
}
pub const fn metadata(&self) -> &M {
&self.1
}
pub fn into_value(self) -> T {
self.0
}
pub fn into_metadata(self) -> M {
self.1
}
pub fn into_parts(self) -> (T, M) {
(self.0, self.1)
}
}
pub trait Strip {
type Stripped;
fn strip(self) -> Self::Stripped;
}
impl<T: Strip, M> Strip for Meta<T, M> {
type Stripped = T::Stripped;
fn strip(self) -> Self::Stripped {
self.0.strip()
}
}
macro_rules! identity_strip {
($($t:ty),* $(,)?) => {
$(
impl Strip for $t {
type Stripped = $t;
fn strip(self) -> Self::Stripped {
self
}
}
)*
};
}
identity_strip!(
BlankIdBuf,
IriBuf,
Id,
Datatype,
Literal,
LiteralType,
Term,
LocalTerm,
usize,
u32,
u64,
i32,
i64,
String
);
impl<S, P, O> Strip for Triple<S, P, O>
where
S: IsSubject + Strip,
P: IsPredicate + Strip,
O: IsObject + Strip,
S::Stripped: IsSubject,
P::Stripped: IsPredicate,
O::Stripped: IsObject,
{
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, P, O, G> Strip for Quad<S, P, O, G>
where
S: IsSubject + Strip,
P: IsPredicate + Strip,
O: IsObject + Strip,
G: IsGraph + Strip,
S::Stripped: IsSubject,
P::Stripped: IsPredicate,
O::Stripped: IsObject,
G::Stripped: IsGraph,
{
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.map(Strip::strip))
}
}
pub type MetaTerm<M> = Meta<Term, M>;
pub type MetaLocalTerm<M> = Meta<LocalTerm, M>;
pub type MetaId<M> = Meta<Id, M>;
pub type MetaLiteral<M> = Meta<Literal, M>;
pub type MetaTriple<M> = Meta<Triple<MetaLocalTerm<M>>, M>;
pub type MetaQuad<M> = Meta<Quad<MetaLocalTerm<M>>, M>;
pub type MetaTripleFull<S, P, O, M> = Meta<Triple<Meta<S, M>, Meta<P, M>, Meta<O, M>>, M>;
pub type MetaQuadFull<S, P, O, G, M> = Meta<Quad<Meta<S, M>, Meta<P, M>, Meta<O, M>, Meta<G, M>>, M>;
impl<S, P, O> Triple<S, P, O>
where
S: IsSubject + Strip,
P: IsPredicate,
O: IsObject + Strip,
S::Stripped: IsSubject,
O::Stripped: IsObject,
{
pub fn strip_all_but_predicate(self) -> Triple<S::Stripped, P, O::Stripped> {
Triple(self.0.strip(), self.1, self.2.strip())
}
}
impl<S, P, O, G> Quad<S, P, O, G>
where
S: IsSubject + Strip,
P: IsPredicate,
O: IsObject + Strip,
G: IsGraph + Strip,
S::Stripped: IsSubject,
O::Stripped: IsObject,
G::Stripped: IsGraph,
{
pub fn strip_all_but_predicate(self) -> Quad<S::Stripped, P, O::Stripped, G::Stripped> {
Quad(self.0.strip(), self.1, self.2.strip(), self.3.map(Strip::strip))
}
}