use iref::IriBuf;
use std::cmp::Ordering;
use std::fmt;
#[cfg(feature = "contextual")]
use contextual::{DisplayWithContext, WithContext};
#[cfg(feature = "meta")]
use locspan_derive::*;
mod blankid;
mod display;
pub mod generator;
mod literal;
mod term;
pub mod vocabulary;
#[cfg(feature = "meta")]
pub mod meta;
pub use blankid::*;
pub use display::*;
pub use generator::Generator;
pub use literal::*;
pub use term::*;
pub use vocabulary::{
BlankIdVocabulary, BlankIdVocabularyMut, IndexVocabulary, IriVocabulary, IriVocabularyMut,
NoVocabulary, Vocabulary, VocabularyMut,
};
#[cfg(feature = "meta")]
pub use generator::MetaGenerator;
pub trait Namespace {
type Id;
}
#[derive(Clone, Copy, Eq, Ord, Hash, Debug)]
#[cfg_attr(
feature = "meta",
derive(
StrippedPartialEq,
StrippedEq,
StrippedPartialOrd,
StrippedOrd,
StrippedHash
)
)]
pub struct Triple<S = Id, P = IriBuf, O = Object>(pub S, pub P, pub O);
impl<S1: PartialEq<S2>, P1: PartialEq<P2>, O1: PartialEq<O2>, S2, P2, O2>
PartialEq<Triple<S2, P2, O2>> for Triple<S1, P1, O1>
{
fn eq(&self, other: &Triple<S2, P2, O2>) -> bool {
self.0 == other.0 && self.1 == other.1 && self.2 == other.2
}
}
impl<S1: PartialOrd<S2>, P1: PartialOrd<P2>, O1: PartialOrd<O2>, S2, P2, O2>
PartialOrd<Triple<S2, P2, O2>> for Triple<S1, P1, O1>
{
fn partial_cmp(&self, other: &Triple<S2, P2, O2>) -> Option<Ordering> {
match self.0.partial_cmp(&other.0) {
Some(Ordering::Equal) => match self.1.partial_cmp(&other.1) {
Some(Ordering::Equal) => self.2.partial_cmp(&other.2),
cmp => cmp,
},
cmp => cmp,
}
}
}
impl Triple {
pub fn into_grdf(self) -> GrdfTriple {
Triple(self.0.into_term(), Term::Id(Id::Iri(self.1)), self.2)
}
}
impl<S, P, O> Triple<S, P, O> {
pub fn new(subject: S, predicate: P, object: O) -> Self {
Self(subject, predicate, object)
}
pub fn subject(&self) -> &S {
&self.0
}
pub fn subject_mut(&mut self) -> &mut S {
&mut self.0
}
pub fn into_subject(self) -> S {
self.0
}
pub fn predicate(&self) -> &P {
&self.1
}
pub fn predicate_mut(&mut self) -> &mut P {
&mut self.1
}
pub fn into_predicate(self) -> P {
self.1
}
pub fn object(&self) -> &O {
&self.2
}
pub fn object_mut(&mut self) -> &mut O {
&mut self.2
}
pub fn into_object(self) -> O {
self.2
}
pub fn into_parts(self) -> (S, P, O) {
(self.0, self.1, self.2)
}
pub fn into_quad<G>(self, graph: Option<G>) -> Quad<S, P, O, G> {
Quad(self.0, self.1, self.2, graph)
}
pub fn map_subject<U>(self, f: impl FnOnce(S) -> U) -> Triple<U, P, O> {
Triple(f(self.0), self.1, self.2)
}
pub fn map_predicate<U>(self, f: impl FnOnce(P) -> U) -> Triple<S, U, O> {
Triple(self.0, f(self.1), self.2)
}
pub fn map_object<U>(self, f: impl FnOnce(O) -> U) -> Triple<S, P, U> {
Triple(self.0, self.1, f(self.2))
}
}
impl<S, L> Triple<Id, IriBuf, Object<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>> {
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Triple<Id<V::Iri, V::BlankId>, V::Iri, Object<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>>
where
S: Clone,
L: Clone,
{
Triple(
self.0.inserted_into(vocabulary),
vocabulary.insert(self.1.as_iri()),
self.2.inserted_into(vocabulary),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Triple<Id<V::Iri, V::BlankId>, V::Iri, Object<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>>
{
Triple(
self.0.insert_into(vocabulary),
vocabulary.insert(self.1.as_iri()),
self.2.insert_into(vocabulary),
)
}
}
impl<S, L>
Quad<
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
>
{
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Triple<
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
>
where
S: Clone,
L: Clone,
{
Triple(
self.0.inserted_into(vocabulary),
self.1.inserted_into(vocabulary),
self.2.inserted_into(vocabulary),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Triple<
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
> {
Triple(
self.0.insert_into(vocabulary),
self.1.insert_into(vocabulary),
self.2.insert_into(vocabulary),
)
}
}
impl<S: RdfDisplay, P: RdfDisplay, O: RdfDisplay> fmt::Display for Triple<S, P, O> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} {} {}",
self.0.rdf_display(),
self.1.rdf_display(),
self.2.rdf_display()
)
}
}
impl<S: RdfDisplay, P: RdfDisplay, O: RdfDisplay> RdfDisplay for Triple<S, P, O> {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} {} {}",
self.0.rdf_display(),
self.1.rdf_display(),
self.2.rdf_display()
)
}
}
#[cfg(feature = "contextual")]
impl<S: RdfDisplayWithContext<V>, P: RdfDisplayWithContext<V>, O: RdfDisplayWithContext<V>, V>
DisplayWithContext<V> for Triple<S, P, O>
{
fn fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} {} {}",
self.0.with(vocabulary).rdf_display(),
self.1.with(vocabulary).rdf_display(),
self.2.with(vocabulary).rdf_display()
)
}
}
#[cfg(feature = "contextual")]
impl<S: RdfDisplayWithContext<V>, P: RdfDisplayWithContext<V>, O: RdfDisplayWithContext<V>, V>
RdfDisplayWithContext<V> for Triple<S, P, O>
{
fn rdf_fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} {} {}",
self.0.with(vocabulary).rdf_display(),
self.1.with(vocabulary).rdf_display(),
self.2.with(vocabulary).rdf_display()
)
}
}
pub type GrdfTriple = Triple<Term, Term, Term>;
#[derive(Clone, Copy, Eq, Ord, Hash, Debug)]
#[cfg_attr(
feature = "meta",
derive(
StrippedPartialEq,
StrippedEq,
StrippedPartialOrd,
StrippedOrd,
StrippedHash
)
)]
pub struct Quad<S = Id, P = IriBuf, O = Object, G = GraphLabel>(pub S, pub P, pub O, pub Option<G>);
impl Quad {
pub fn into_grdf(self) -> GrdfQuad {
Quad(
self.0.into_term(),
Term::Id(Id::Iri(self.1)),
self.2,
self.3.map(GraphLabel::into_term),
)
}
}
impl<S, L> Quad<Id, IriBuf, Object<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>, GraphLabel> {
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Quad<
Id<V::Iri, V::BlankId>,
V::Iri,
Object<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
GraphLabel<V::Iri, V::BlankId>,
>
where
S: Clone,
L: Clone,
{
Quad(
self.0.inserted_into(vocabulary),
vocabulary.insert(self.1.as_iri()),
self.2.inserted_into(vocabulary),
self.3.as_ref().map(|g| g.inserted_into(vocabulary)),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Quad<
Id<V::Iri, V::BlankId>,
V::Iri,
Object<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
GraphLabel<V::Iri, V::BlankId>,
> {
Quad(
self.0.insert_into(vocabulary),
vocabulary.insert(self.1.as_iri()),
self.2.insert_into(vocabulary),
self.3.map(|g| g.insert_into(vocabulary)),
)
}
}
impl<S, L>
Quad<
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
Term<Id<IriBuf, BlankIdBuf>, Literal<S, IriBuf, L>>,
>
{
#[allow(clippy::type_complexity)]
pub fn inserted_into<V: VocabularyMut>(
&self,
vocabulary: &mut V,
) -> Quad<
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
>
where
S: Clone,
L: Clone,
{
Quad(
self.0.inserted_into(vocabulary),
self.1.inserted_into(vocabulary),
self.2.inserted_into(vocabulary),
self.3.as_ref().map(|g| g.inserted_into(vocabulary)),
)
}
#[allow(clippy::type_complexity)]
pub fn insert_into<V: VocabularyMut>(
self,
vocabulary: &mut V,
) -> Quad<
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
Term<Id<V::Iri, V::BlankId>, Literal<S, V::Iri, L>>,
> {
Quad(
self.0.insert_into(vocabulary),
self.1.insert_into(vocabulary),
self.2.insert_into(vocabulary),
self.3.map(|g| g.insert_into(vocabulary)),
)
}
}
impl<S, P, O, G> Quad<S, P, O, G> {
pub fn new(subject: S, predicate: P, object: O, graph: Option<G>) -> Self {
Self(subject, predicate, object, graph)
}
pub fn subject(&self) -> &S {
&self.0
}
pub fn subject_mut(&mut self) -> &mut S {
&mut self.0
}
pub fn into_subject(self) -> S {
self.0
}
pub fn predicate(&self) -> &P {
&self.1
}
pub fn predicate_mut(&mut self) -> &mut P {
&mut self.1
}
pub fn into_predicate(self) -> P {
self.1
}
pub fn object(&self) -> &O {
&self.2
}
pub fn object_mut(&mut self) -> &mut O {
&mut self.2
}
pub fn into_object(self) -> O {
self.2
}
pub fn graph(&self) -> Option<&G> {
self.3.as_ref()
}
pub fn graph_mut(&mut self) -> Option<&mut G> {
self.3.as_mut()
}
pub fn into_graph(self) -> Option<G> {
self.3
}
pub fn into_parts(self) -> (S, P, O, Option<G>) {
(self.0, self.1, self.2, self.3)
}
pub fn into_triple(self) -> (Triple<S, P, O>, Option<G>) {
(Triple(self.0, self.1, self.2), self.3)
}
pub fn map_subject<U>(self, f: impl FnOnce(S) -> U) -> Quad<U, P, O, G> {
Quad(f(self.0), self.1, self.2, self.3)
}
pub fn map_predicate<U>(self, f: impl FnOnce(P) -> U) -> Quad<S, U, O, G> {
Quad(self.0, f(self.1), self.2, self.3)
}
pub fn map_object<U>(self, f: impl FnOnce(O) -> U) -> Quad<S, P, U, G> {
Quad(self.0, self.1, f(self.2), self.3)
}
pub fn map_graph<U>(self, f: impl FnOnce(Option<G>) -> Option<U>) -> Quad<S, P, O, U> {
Quad(self.0, self.1, self.2, f(self.3))
}
}
impl<
S1: PartialEq<S2>,
P1: PartialEq<P2>,
O1: PartialEq<O2>,
G1: PartialEq<G2>,
S2,
P2,
O2,
G2,
> PartialEq<Quad<S2, P2, O2, G2>> for Quad<S1, P1, O1, G1>
{
fn eq(&self, other: &Quad<S2, P2, O2, G2>) -> bool {
self.0 == other.0
&& self.1 == other.1
&& self.2 == other.2
&& match (&self.3, &other.3) {
(Some(a), Some(b)) => a == b,
(None, None) => true,
_ => false,
}
}
}
impl<
S1: PartialOrd<S2>,
P1: PartialOrd<P2>,
O1: PartialOrd<O2>,
G1: PartialOrd<G2>,
S2,
P2,
O2,
G2,
> PartialOrd<Quad<S2, P2, O2, G2>> for Quad<S1, P1, O1, G1>
{
fn partial_cmp(&self, other: &Quad<S2, P2, O2, G2>) -> Option<Ordering> {
match self.0.partial_cmp(&other.0) {
Some(Ordering::Equal) => match self.1.partial_cmp(&other.1) {
Some(Ordering::Equal) => match self.2.partial_cmp(&other.2) {
Some(Ordering::Equal) => match (&self.3, &other.3) {
(Some(a), Some(b)) => a.partial_cmp(b),
(Some(_), None) => Some(Ordering::Greater),
(None, Some(_)) => Some(Ordering::Less),
(None, None) => Some(Ordering::Equal),
},
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
}
}
}
impl<S: RdfDisplay, P: RdfDisplay, O: RdfDisplay, G: RdfDisplay> fmt::Display for Quad<S, P, O, G> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.graph() {
Some(graph) => write!(
f,
"{} {} {} {}",
self.0.rdf_display(),
self.1.rdf_display(),
self.2.rdf_display(),
graph.rdf_display()
),
None => write!(
f,
"{} {} {}",
self.0.rdf_display(),
self.1.rdf_display(),
self.2.rdf_display()
),
}
}
}
impl<S: RdfDisplay, P: RdfDisplay, O: RdfDisplay, G: RdfDisplay> RdfDisplay for Quad<S, P, O, G> {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.graph() {
Some(graph) => write!(
f,
"{} {} {} {}",
self.0.rdf_display(),
self.1.rdf_display(),
self.2.rdf_display(),
graph.rdf_display()
),
None => write!(
f,
"{} {} {}",
self.0.rdf_display(),
self.1.rdf_display(),
self.2.rdf_display()
),
}
}
}
#[cfg(feature = "contextual")]
impl<
S: RdfDisplayWithContext<V>,
P: RdfDisplayWithContext<V>,
O: RdfDisplayWithContext<V>,
G: RdfDisplayWithContext<V>,
V,
> DisplayWithContext<V> for Quad<S, P, O, G>
{
fn fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
match self.graph() {
Some(graph) => write!(
f,
"{} {} {} {}",
self.0.with(vocabulary).rdf_display(),
self.1.with(vocabulary).rdf_display(),
self.2.with(vocabulary).rdf_display(),
graph.with(vocabulary).rdf_display()
),
None => write!(
f,
"{} {} {}",
self.0.with(vocabulary).rdf_display(),
self.1.with(vocabulary).rdf_display(),
self.2.with(vocabulary).rdf_display()
),
}
}
}
#[cfg(feature = "contextual")]
impl<
S: RdfDisplayWithContext<V>,
P: RdfDisplayWithContext<V>,
O: RdfDisplayWithContext<V>,
G: RdfDisplayWithContext<V>,
V,
> RdfDisplayWithContext<V> for Quad<S, P, O, G>
{
fn rdf_fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
match self.graph() {
Some(graph) => write!(
f,
"{} {} {} {}",
self.0.with(vocabulary).rdf_display(),
self.1.with(vocabulary).rdf_display(),
self.2.with(vocabulary).rdf_display(),
graph.with(vocabulary).rdf_display()
),
None => write!(
f,
"{} {} {}",
self.0.with(vocabulary).rdf_display(),
self.1.with(vocabulary).rdf_display(),
self.2.with(vocabulary).rdf_display()
),
}
}
}
pub type GrdfQuad = Quad<Term, Term, Term, Term>;