Skip to content

Commit

Permalink
feat(rdf): implement owned quad model
Browse files Browse the repository at this point in the history
  • Loading branch information
amimart committed Feb 5, 2024
1 parent 0ae1166 commit c2acec0
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/okp4-rdf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod dataset;
pub mod normalize;
mod owned_model;
pub mod serde;
pub mod uri;
156 changes: 156 additions & 0 deletions packages/okp4-rdf/src/owned_model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
use rio_api::model::{BlankNode, GraphName, Literal, NamedNode, Quad, Subject, Term};

#[derive(Debug)]
pub struct RDFStarUnsupported;

pub struct OwnedQuad {
subject: OwnedSubject,
predicate: String,
object: OwnedTerm,
graph_name: Option<OwnedGraphName>,
}

impl TryFrom<Quad<'_>> for OwnedQuad {
type Error = RDFStarUnsupported;

fn try_from(value: Quad<'_>) -> Result<Self, Self::Error> {
Ok(Self {
subject: value.subject.try_into()?,
predicate: value.predicate.iri.to_owned(),
object: value.object.try_into()?,
graph_name: value.graph_name.map(OwnedGraphName::from),
})
}
}

impl<'a> From<&'a OwnedQuad> for Quad<'a> {
fn from(value: &'a OwnedQuad) -> Self {
Self {
subject: (&value.subject).into(),
predicate: NamedNode {
iri: value.predicate.as_str(),
},
object: (&value.object).into(),
graph_name: match &value.graph_name {
None => None,
Some(g) => Some(g.into()),
},
}
}
}

pub enum Id {
Named(String),
Blank(String),
}

pub type OwnedSubject = Id;

impl TryFrom<Subject<'_>> for OwnedSubject {
type Error = RDFStarUnsupported;

fn try_from(value: Subject<'_>) -> Result<Self, Self::Error> {
Ok(match value {
Subject::NamedNode(n) => Self::Named(n.iri.to_owned()),
Subject::BlankNode(n) => Self::Blank(n.id.to_owned()),
Subject::Triple(_) => Err(RDFStarUnsupported {})?,
})
}
}

impl<'a> From<&'a OwnedSubject> for Subject<'a> {
fn from(value: &'a OwnedSubject) -> Self {
match value {
OwnedSubject::Named(iri) => NamedNode { iri }.into(),
OwnedSubject::Blank(id) => BlankNode { id }.into(),
}
}
}

pub type OwnedGraphName = Id;

impl From<GraphName<'_>> for OwnedGraphName {
fn from(value: GraphName<'_>) -> Self {
match value {
GraphName::NamedNode(n) => Self::Named(n.iri.to_owned()),
GraphName::BlankNode(n) => Self::Blank(n.id.to_owned()),
}
}
}

impl<'a> From<&'a OwnedGraphName> for GraphName<'a> {
fn from(value: &'a OwnedGraphName) -> Self {
match value {
OwnedGraphName::Named(iri) => NamedNode { iri }.into(),
OwnedGraphName::Blank(id) => BlankNode { id }.into(),
}
}
}

pub enum OwnedTerm {
Named(String),
Blank(String),
Literal(OwnedLiteral),
}

impl TryFrom<Term<'_>> for OwnedTerm {
type Error = RDFStarUnsupported;

fn try_from(value: Term<'_>) -> Result<Self, Self::Error> {
Ok(match value {
Term::NamedNode(n) => OwnedTerm::Named(n.iri.to_owned()),
Term::BlankNode(n) => OwnedTerm::Blank(n.id.to_owned()),
Term::Literal(l) => OwnedTerm::Literal(l.into()),
Term::Triple(_) => Err(RDFStarUnsupported)?,
})
}
}

impl<'a> From<&'a OwnedTerm> for Term<'a> {
fn from(value: &'a OwnedTerm) -> Self {
match value {
OwnedTerm::Named(iri) => NamedNode { iri }.into(),
OwnedTerm::Blank(id) => BlankNode { id }.into(),
OwnedTerm::Literal(l) => Term::Literal(l.into()),
}
}
}

pub enum OwnedLiteral {
Simple(String),
LanguageTaggedString { value: String, language: String },
Typed { value: String, datatype: String },
}

impl From<Literal<'_>> for OwnedLiteral {
fn from(value: Literal<'_>) -> Self {
match value {
Literal::Simple { value } => OwnedLiteral::Simple(value.to_owned()),
Literal::LanguageTaggedString { value, language } => {
OwnedLiteral::LanguageTaggedString {
value: value.to_owned(),
language: language.to_owned(),
}
}
Literal::Typed { value, datatype } => OwnedLiteral::Typed {
value: value.to_owned(),
datatype: datatype.iri.to_owned(),
},
}
}
}

impl<'a> From<&'a OwnedLiteral> for Literal<'a> {
fn from(l: &'a OwnedLiteral) -> Self {
match l {
OwnedLiteral::Simple(value) => Literal::Simple { value },
OwnedLiteral::LanguageTaggedString { value, language } => {
Literal::LanguageTaggedString { value, language }
}
OwnedLiteral::Typed { value, datatype } => Literal::Typed {
value,
datatype: NamedNode { iri: datatype },
},
}
}
}

0 comments on commit c2acec0

Please sign in to comment.