use source_span::Loc;
use iref::{
Iri,
IriBuf
};
pub type BlankNode = String;
#[derive(Clone, Debug)]
pub enum IriRef {
Iri(IriBuf),
Curie(Option<String>, String)
}
impl IriRef {
pub fn curie_from_str(s: &str) -> IriRef {
if let Some(i) = s.find(':') {
let (prefix, id) = s.split_at(i);
let (_, id) = id.split_at(1);
IriRef::Curie(Some(prefix.to_string()), id.to_string())
} else {
IriRef::Curie(None, s.to_string())
}
}
}
pub struct Document {
pub statements: Vec<Loc<Statement>>
}
impl Document {
pub fn base_prefix(&self) -> Option<Iri> {
for stm in &self.statements {
match stm.as_ref() {
Statement::Directive(Directive::Base(iri)) => return Some(iri.as_iri()),
_ => ()
}
}
None
}
}
pub enum Statement {
Directive(Directive),
Triples(Loc<Subject>, Loc<Vec<Loc<VerbObjects>>>),
}
pub enum Directive {
Prefix(Loc<String>, Loc<IriBuf>),
Base(Loc<IriBuf>)
}
pub struct VerbObjects {
pub verb: Loc<Verb>,
pub objects: Loc<Vec<Loc<Object>>>
}
#[derive(Debug)]
pub enum Verb {
A,
Predicate(IriRef)
}
impl<'a> From<&'a str> for Verb {
fn from(s: &'a str) -> Verb {
if s == "a" {
Verb::A
} else {
if let Some(i) = s.find(':') {
let (prefix, id) = s.split_at(i);
let (_, id) = id.split_at(1);
Verb::Predicate(IriRef::Curie(Some(prefix.to_string()), id.to_string()))
} else {
Verb::Predicate(IriRef::Curie(None, s.to_string()))
}
}
}
}
pub enum Subject {
Iri(IriRef),
BlankNode(BlankNode),
Collection(Vec<Loc<Subject>>),
Blank(Vec<Loc<VerbObjects>>)
}
impl<'a> From<&'a str> for Subject {
fn from(s: &'a str) -> Subject {
if let Some(i) = s.find(':') {
let (prefix, id) = s.split_at(i);
if prefix == "_" {
Subject::BlankNode(id.to_string())
} else {
let (_, id) = id.split_at(1);
Subject::Iri(IriRef::Curie(Some(prefix.to_string()), id.to_string()))
}
} else {
Subject::Iri(IriRef::Curie(None, s.to_string()))
}
}
}
pub enum Object {
Iri(IriRef),
BlankNode(BlankNode),
Collection(Vec<Loc<Object>>),
Blank(Vec<Loc<VerbObjects>>),
Literal(Literal)
}
impl<'a> From<&'a str> for Object {
fn from(s: &'a str) -> Object {
if let Some(i) = s.find(':') {
let (prefix, id) = s.split_at(i);
if prefix == "_" {
Object::BlankNode(id.to_string())
} else {
let (_, id) = id.split_at(1);
Object::Iri(IriRef::Curie(Some(prefix.to_string()), id.to_string()))
}
} else {
Object::Iri(IriRef::Curie(None, s.to_string()))
}
}
}
pub enum Literal {
String(String, Option<Loc<Tag>>),
Numeric(Numeric),
Boolean(bool)
}
pub enum Tag {
Lang(String),
Iri(IriRef)
}
#[derive(Clone, Copy, Debug)]
pub enum Numeric {
Int(i64),
Decimal(bool, u32, u32),
Double(bool, u32, u32, i32) }