oxjelly 0.0.0

Parser and serializer for Jelly
Documentation
use std::cmp::Ordering;
use crate::jelly::rdf::rdf_literal::LiteralKind;
use crate::jelly::rdf::{RdfIri, RdfLiteral};
use crate::jelly::rdf::rdf_quad::{Graph, Object, Predicate, Subject};

fn compare_jelly_iris(x: &RdfIri, y: &RdfIri) -> Option<Ordering> {
    x.prefix_id.partial_cmp(&y.prefix_id)
        .map(|ord| match ord {
            Ordering::Equal => x.name_id.partial_cmp(&y.name_id),
            _ => Some(ord),
        }).flatten()
}

fn compare_jelly_literal_kinds(x: &LiteralKind, y: &LiteralKind) -> Option<Ordering> {
    match (x, y) {
        (LiteralKind::Datatype(datatype_x), LiteralKind::Datatype(datatype_y)) => datatype_x.partial_cmp(&datatype_y),
        (LiteralKind::Langtag(tag_x), LiteralKind::Langtag(tag_y)) => tag_x.partial_cmp(&tag_y),
        _ => None,
    }
}

fn compare_jelly_literals(x: &RdfLiteral, y: &RdfLiteral) -> Option<Ordering> {
    x.lex.partial_cmp(&y.lex)
        .map(|ord| match ord {
            Ordering::Equal => match (&x.literalKind, &y.literalKind) {
                (Some(x), Some(y)) => compare_jelly_literal_kinds(x, y),
                _ => None,
            }
            _ => Some(ord),
        }).flatten()
}

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct SortableSubject(pub(crate) Subject);

impl PartialOrd for SortableSubject {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match (&self.0, &other.0) {
            (Subject::SIri(x), Subject::SIri(y)) => compare_jelly_iris(x, y),
            (Subject::SBnode(x), Subject::SBnode(y)) => x.partial_cmp(&y),
            _ => todo!(),
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct SortablePredicate(pub(crate) Predicate);

impl PartialOrd for SortablePredicate {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match (&self.0, &other.0) {
            (Predicate::PIri(x), Predicate::PIri(y)) => compare_jelly_iris(x, y),
            _ => todo!()
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct SortableObject(pub(crate) Object);

impl PartialOrd for SortableObject {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match (&self.0, &other.0) {
            (Object::OIri(x), Object::OIri(y)) => compare_jelly_iris(x, y),
            (Object::OBnode(x), Object::OBnode(y)) => x.partial_cmp(y),
            (Object::OLiteral(x), Object::OLiteral(y)) => compare_jelly_literals(x, y),
            (Object::OTripleTerm(_x), Object::OTripleTerm(_y)) => todo!(),
            _ => None,
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct SortableGraphName(pub(crate) Graph);

impl PartialOrd for SortableGraphName {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match (&self.0, &other.0) {
            (Graph::GIri(x), Graph::GIri(y)) => compare_jelly_iris(x, y),
            (Graph::GDefaultGraph(_), Graph::GDefaultGraph(_)) => Some(Ordering::Equal),
            _ => todo!()
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct SortableRdfQuad {
    pub(crate) subject: SortableSubject,
    pub(crate) predicate: SortablePredicate,
    pub(crate) object: SortableObject,
    pub(crate) graph_name: SortableGraphName
}

impl Eq for SortableRdfQuad {}

impl PartialOrd<Self> for SortableRdfQuad {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.subject.partial_cmp(&other.subject)
            .map(|ord| if ord == Ordering::Equal {
                self.predicate.partial_cmp(&other.predicate)
                    .map(|ord| if ord == Ordering::Equal {
                        self.object.partial_cmp(&other.object)
                            .map(|ord| if ord == Ordering::Equal {
                                self.graph_name.partial_cmp(&other.graph_name)
                            } else { None })
                    } else { None })
            } else { None }).flatten().flatten().flatten()
    }
}

impl Ord for SortableRdfQuad {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap_or(Ordering::Less)
    }
}