use constants;
use iter::SortedIterator;
use std::cmp::Ordering;
use std::marker::PhantomData;
pub trait BlankNodePtr<'g> {
fn to_blank_node_or_iri<I>(&self) -> BlankNodeOrIRI<'g, Self, I>
where
Self: Clone,
I: IRIPtr<'g>,
{
BlankNodeOrIRI::BlankNode(self.clone(), PhantomData)
}
fn to_resource<I, L>(&self) -> Resource<'g, Self, I, L>
where
Self: Clone,
I: IRIPtr<'g>,
L: LiteralPtr<'g>,
{
Resource::BlankNode(self.clone(), PhantomData)
}
}
pub trait IRIPtr<'g> {
fn as_str(&self) -> &str;
fn to_blank_node_or_iri<B>(&self) -> BlankNodeOrIRI<'g, B, Self>
where
Self: Clone,
B: BlankNodePtr<'g>,
{
BlankNodeOrIRI::IRI(self.clone())
}
fn to_resource<B, L>(&self) -> Resource<'g, B, Self, L>
where
Self: Clone,
B: BlankNodePtr<'g>,
L: LiteralPtr<'g>,
{
Resource::IRI(self.clone())
}
}
impl<'g> PartialEq for IRIPtr<'g> {
fn eq(&self, other: &IRIPtr<'g>) -> bool {
self.as_str() == other.as_str()
}
}
impl<'g> Eq for IRIPtr<'g> {}
impl<'g> PartialOrd for IRIPtr<'g> {
fn partial_cmp(&self, other: &IRIPtr<'g>) -> Option<Ordering> {
Some(self.as_str().cmp(other.as_str()))
}
}
impl<'g> Ord for IRIPtr<'g> {
fn cmp(&self, other: &IRIPtr<'g>) -> Ordering {
self.as_str().cmp(other.as_str())
}
}
pub trait DatatypePtr<'g> {
fn as_str(&self) -> &str;
}
pub trait LiteralPtr<'g> {
type DatatypePtr: DatatypePtr<'g> + PartialEq;
fn as_str(&self) -> &str;
fn datatype(&self) -> Self::DatatypePtr;
fn datatype_str(&self) -> &str;
fn language(&self) -> Option<&str>;
fn to_resource<B, I>(&self) -> Resource<'g, B, I, Self>
where
Self: Clone,
B: BlankNodePtr<'g>,
I: IRIPtr<'g>,
{
Resource::Literal(self.clone())
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
pub enum BlankNodeOrIRI<'g, B: 'g, I: 'g>
where
B: BlankNodePtr<'g>,
I: IRIPtr<'g>,
{
BlankNode(B, PhantomData<&'g u8>),
IRI(I),
}
impl<'g, B, I> BlankNodeOrIRI<'g, B, I>
where
B: BlankNodePtr<'g> + Clone,
I: IRIPtr<'g> + Clone,
{
pub fn is_blank_node(&self) -> bool {
match *self {
BlankNodeOrIRI::BlankNode(_, _) => true,
_ => false,
}
}
pub fn is_iri(&self) -> bool {
match *self {
BlankNodeOrIRI::IRI(_) => true,
_ => false,
}
}
pub fn as_blank_node(&self) -> Option<&B> {
match *self {
BlankNodeOrIRI::BlankNode(ref b, _) => Some(b),
_ => None,
}
}
pub fn as_iri(&self) -> Option<&I> {
match *self {
BlankNodeOrIRI::IRI(ref i) => Some(i),
_ => None,
}
}
pub fn to_resource<L>(&self) -> Resource<'g, B, I, L>
where
Self: Clone,
L: LiteralPtr<'g>,
{
match *self {
BlankNodeOrIRI::BlankNode(ref b, _) => Resource::BlankNode(b.clone(), PhantomData),
BlankNodeOrIRI::IRI(ref i) => Resource::IRI(i.clone()),
}
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
pub enum Resource<'g, B: 'g, I: 'g, L: 'g>
where
B: BlankNodePtr<'g>,
I: IRIPtr<'g>,
L: LiteralPtr<'g>,
{
BlankNode(B, PhantomData<&'g u8>),
IRI(I),
Literal(L),
}
impl<'g, B, I, L> Resource<'g, B, I, L>
where
B: BlankNodePtr<'g>,
I: IRIPtr<'g>,
L: LiteralPtr<'g>,
{
pub fn is_blank_node(&self) -> bool {
match *self {
Resource::BlankNode(_, _) => true,
_ => false,
}
}
pub fn is_iri(&self) -> bool {
match *self {
Resource::IRI(_) => true,
_ => false,
}
}
pub fn is_literal(&self) -> bool {
match *self {
Resource::Literal(_) => true,
_ => false,
}
}
pub fn as_blank_node(&self) -> Option<&B> {
match *self {
Resource::BlankNode(ref b, _) => Some(b),
_ => None,
}
}
pub fn as_iri(&self) -> Option<&I> {
match *self {
Resource::IRI(ref t) => Some(t),
_ => None,
}
}
pub fn as_literal(&self) -> Option<&L> {
match *self {
Resource::Literal(ref t) => Some(t),
_ => None,
}
}
pub fn to_blank_node_or_iri(&self) -> Option<BlankNodeOrIRI<'g, B, I>>
where
B: Clone,
I: Clone,
{
match *self {
Resource::BlankNode(ref b, _) => {
Some(BlankNodeOrIRI::BlankNode(b.clone(), PhantomData))
}
Resource::IRI(ref i) => Some(BlankNodeOrIRI::IRI(i.clone())),
_ => None,
}
}
}
pub trait Triple<'g, B, I, L>
where
B: BlankNodePtr<'g>,
I: IRIPtr<'g>,
L: LiteralPtr<'g>,
{
fn subject(&self) -> BlankNodeOrIRI<'g, B, I>;
fn predicate(&self) -> I;
fn object(&self) -> Resource<'g, B, I, L>;
}
pub enum WriterBlankNodeOrIRI<'g, W>
where
W: GraphWriter<'g>,
{
BlankNode(W::BlankNode, PhantomData<&'g u8>),
IRI(W::IRI),
}
pub enum WriterResource<'g, W>
where
W: GraphWriter<'g>,
{
BlankNode(W::BlankNode, PhantomData<&'g u8>),
IRI(W::IRI),
Literal(W::Literal),
}
pub trait ResourceTranslator<'g> {
type Graph: Graph<'g>;
type GraphWriter: GraphWriter<'g>;
fn translate_blank_node(
&mut self,
w: &mut Self::GraphWriter,
blank_node: &<Self::Graph as Graph<'g>>::BlankNodePtr,
) -> <Self::GraphWriter as GraphWriter<'g>>::BlankNode;
fn translate_blank_node_or_iri(
&mut self,
w: &mut Self::GraphWriter,
blank_node_or_iri: &BlankNodeOrIRI<
'g,
<Self::Graph as Graph<'g>>::BlankNodePtr,
<Self::Graph as Graph<'g>>::IRIPtr,
>,
) -> WriterBlankNodeOrIRI<'g, Self::GraphWriter>
where
Self: 'g,
{
match *blank_node_or_iri {
BlankNodeOrIRI::BlankNode(ref b, p) => {
WriterBlankNodeOrIRI::BlankNode(self.translate_blank_node(w, b), p)
}
BlankNodeOrIRI::IRI(ref i) => WriterBlankNodeOrIRI::IRI(w.create_iri(i)),
}
}
fn translate_resource(
&mut self,
w: &mut Self::GraphWriter,
resource: &R<'g, Self::Graph>,
) -> WriterResource<'g, Self::GraphWriter>
where
Self: 'g,
{
match *resource {
Resource::BlankNode(ref b, p) => {
WriterResource::BlankNode(self.translate_blank_node(w, b), p)
}
Resource::IRI(ref i) => WriterResource::IRI(w.create_iri(i)),
Resource::Literal(ref l) => WriterResource::Literal(w.create_literal(l)),
}
}
}
type R<'g, G> = Resource<
'g,
<G as Graph<'g>>::BlankNodePtr,
<G as Graph<'g>>::IRIPtr,
<G as Graph<'g>>::LiteralPtr,
>;
pub trait GraphWriter<'g> {
type BlankNode: Clone;
type IRI: Clone;
type Literal;
type Datatype: Clone;
type Language;
type Graph: Graph<'g>;
fn create_blank_node(&mut self) -> Self::BlankNode;
fn create_iri<'a, I: 'a>(&mut self, &I) -> Self::IRI
where
I: IRIPtr<'a>;
fn create_literal<'a, L: 'a>(&mut self, &L) -> Self::Literal
where
L: LiteralPtr<'a>;
fn create_datatype(&mut self, &str) -> Self::Datatype;
fn create_language(&mut self, &str) -> Self::Language;
fn create_literal_datatype(&mut self, value: &str, datatype: &Self::Datatype) -> Self::Literal;
fn create_literal_language(&mut self, value: &str, language: &Self::Language) -> Self::Literal;
fn add(
&mut self,
subject: &WriterBlankNodeOrIRI<'g, Self>,
predicate: &Self::IRI,
object: &WriterResource<'g, Self>,
) where
Self: Sized,
{
match *subject {
WriterBlankNodeOrIRI::BlankNode(ref subject, _) => match *object {
WriterResource::BlankNode(ref object, _) => {
self.add_blank_blank(subject, predicate, object);
}
WriterResource::IRI(ref object) => {
GraphWriter::add_blank_iri(self, subject, predicate, object);
}
WriterResource::Literal(ref object) => {
GraphWriter::add_blank_literal(self, subject, predicate, object);
}
},
WriterBlankNodeOrIRI::IRI(ref subject) => match *object {
WriterResource::BlankNode(ref object, _) => {
GraphWriter::add_iri_blank(self, subject, predicate, object);
}
WriterResource::IRI(ref object) => {
GraphWriter::add_iri_iri(self, subject, predicate, object);
}
WriterResource::Literal(ref object) => {
GraphWriter::add_iri_literal(self, subject, predicate, object);
}
},
}
}
fn add_blank_blank(
&mut self,
subject: &Self::BlankNode,
predicate: &Self::IRI,
object: &Self::BlankNode,
);
fn add_blank_iri(
&mut self,
subject: &Self::BlankNode,
predicate: &Self::IRI,
object: &Self::IRI,
);
fn add_blank_literal(
&mut self,
subject: &Self::BlankNode,
predicate: &Self::IRI,
bject: &Self::Literal,
);
fn add_iri_blank(
&mut self,
subject: &Self::IRI,
predicate: &Self::IRI,
object: &Self::BlankNode,
);
fn add_iri_iri(&mut self, subject: &Self::IRI, predicate: &Self::IRI, object: &Self::IRI);
fn add_iri_literal(
&mut self,
subject: &Self::IRI,
predicate: &Self::IRI,
object: &Self::Literal,
);
fn collect(self) -> Self::Graph;
}
pub trait Graph<'g> {
type BlankNodePtr: BlankNodePtr<'g> + Ord + Clone + 'g;
type IRIPtr: IRIPtr<'g> + Ord + Clone + 'g;
type LiteralPtr: LiteralPtr<'g> + Ord + Clone;
type SPOTriple: Triple<'g, Self::BlankNodePtr, Self::IRIPtr, Self::LiteralPtr> + Ord + Clone;
type SPOIter: SortedIterator<Item = Self::SPOTriple>;
type SPORangeIter: SortedIterator<Item = Self::SPOTriple>;
type OPSTriple: Triple<'g, Self::BlankNodePtr, Self::IRIPtr, Self::LiteralPtr> + Ord + Clone;
type OPSRangeIter: SortedIterator<Item = Self::OPSTriple>;
fn iter(&'g self) -> Self::SPOIter;
fn find_datatype<'a>(
&'g self,
datatype: &'a str,
) -> Option<<Self::LiteralPtr as LiteralPtr<'g>>::DatatypePtr>;
fn find_iri<'a>(&'g self, iri: &'a str) -> Option<Self::IRIPtr>;
fn find_literal<'a>(
&'g self,
literal: &'a str,
datatype: &'a str,
language: Option<&'a str>,
) -> Option<Self::LiteralPtr>;
fn iter_s(
&'g self,
subject: &BlankNodeOrIRI<'g, Self::BlankNodePtr, Self::IRIPtr>,
) -> Self::SPORangeIter;
fn iter_s_p(
&'g self,
subject: &BlankNodeOrIRI<'g, Self::BlankNodePtr, Self::IRIPtr>,
predicate: &Self::IRIPtr,
) -> Self::SPORangeIter;
fn iter_o(
&'g self,
object: &Resource<'g, Self::BlankNodePtr, Self::IRIPtr, Self::LiteralPtr>,
) -> Self::OPSRangeIter;
fn iter_o_p(
&'g self,
object: &Resource<'g, Self::BlankNodePtr, Self::IRIPtr, Self::LiteralPtr>,
predicate: &Self::IRIPtr,
) -> Self::OPSRangeIter;
fn empty_spo_range(&'g self) -> Self::SPORangeIter;
fn empty_ops_range(&'g self) -> Self::OPSRangeIter;
}
impl<'g> IRIPtr<'g> for &'g str {
fn as_str(&self) -> &str {
*self
}
}
impl<'g> IRIPtr<'g> for String {
fn as_str(&self) -> &str {
self.as_str()
}
}
impl<'g> DatatypePtr<'g> for &'g str {
fn as_str(&self) -> &str {
*self
}
}
impl<'g> LiteralPtr<'g> for &'g str {
type DatatypePtr = &'g str;
fn as_str(&self) -> &str {
*self
}
fn datatype(&self) -> &'g str {
constants::XSD_STRING
}
fn datatype_str(&self) -> &str {
constants::XSD_STRING
}
fn language(&self) -> Option<&str> {
None
}
}
impl<'g> LiteralPtr<'g> for String {
type DatatypePtr = &'g str;
fn as_str(&self) -> &str {
self.as_str()
}
fn datatype(&self) -> &'g str {
constants::XSD_STRING
}
fn datatype_str(&self) -> &str {
constants::XSD_STRING
}
fn language(&self) -> Option<&str> {
None
}
}