Move supporting types to other modules

This commit is contained in:
asonix 2022-12-16 01:40:31 -06:00
parent ae04935f2a
commit 5045e9881c
9 changed files with 829 additions and 749 deletions

View file

@ -0,0 +1,42 @@
use crate::rdf::subject_string;
use indexmap::{IndexMap, IndexSet};
use json_ld::ValidId as Subject;
use rdf_types::Vocabulary;
#[derive(Default)]
pub(crate) struct CompoundLiteralSubjects {
graphs: IndexMap<String, CompoundMap>,
}
impl CompoundLiteralSubjects {
pub(crate) fn graph_entry(
&mut self,
graph: String,
) -> indexmap::map::Entry<'_, String, CompoundMap> {
self.graphs.entry(graph)
}
pub(crate) fn graph(&self, graph: &str) -> Option<&CompoundMap> {
self.graphs.get(graph)
}
}
#[derive(Default)]
pub(crate) struct CompoundMap {
subjects: IndexSet<String>,
}
impl CompoundMap {
pub(crate) fn insert<N>(&mut self, subject: &Subject<N::Iri, N::BlankId>, vocabulary: &N)
where
N: Vocabulary,
{
let subject = subject_string(subject, vocabulary);
self.subjects.insert(subject);
}
pub(crate) fn iter(&self) -> indexmap::set::Iter<'_, String> {
self.subjects.iter()
}
}

View file

@ -0,0 +1,144 @@
use crate::{
json_value::{JsonValue, Map},
object_entry::ObjectEntry,
rdf::{subject_string, QuadSubject},
referenced_once::ReferencedValue,
subject_entry::SubjectEntry,
};
use indexmap::{IndexMap, IndexSet};
use rdf_types::Vocabulary;
use std::{cell::RefCell, rc::Rc};
#[derive(Default)]
pub(crate) struct GraphMap {
graphs: IndexMap<String, Rc<RefCell<GraphEntry>>>,
}
#[derive(Default)]
pub(crate) struct GraphEntry {
// short for
// {graph_name} -> Map
// @id -> {graph_name}
graphs: IndexSet<String>,
// short for
// {subject} -> Map
// @id -> {subject}
// @type -> Array
// {object}
// {predicate} -> Array
// {object}
subjects: IndexMap<String, Rc<RefCell<SubjectEntry>>>,
// short for
// {object} -> Map
// @id -> {object}
// short for
// {object} -> Map
// @id -> {object}
objects: IndexMap<String, Rc<RefCell<ObjectEntry>>>,
// short for
// nil -> Map
// usages -> Array
// node -> Map (SubjectEntry)
// property -> {predicate}
// value -> {object}
usages: Rc<RefCell<Option<Vec<ReferencedValue>>>>,
}
impl GraphMap {
pub(crate) fn insert(&mut self, graph_name: String, graph_entry: Rc<RefCell<GraphEntry>>) {
self.graphs.insert(graph_name, graph_entry);
}
pub(crate) fn entry(
&mut self,
graph_name: String,
) -> indexmap::map::Entry<'_, String, Rc<RefCell<GraphEntry>>> {
self.graphs.entry(graph_name)
}
pub(crate) fn iter(&self) -> indexmap::map::Iter<'_, String, Rc<RefCell<GraphEntry>>> {
self.graphs.iter()
}
pub(crate) fn get(&self, graph: &str) -> Option<&Rc<RefCell<GraphEntry>>> {
self.graphs.get(graph)
}
}
impl GraphEntry {
pub(crate) fn contains_graph(&self, graph_name: &str) -> bool {
self.graphs.contains(graph_name)
}
pub(crate) fn insert_graph(&mut self, graph_name: String) {
self.graphs.insert(graph_name);
}
pub(crate) fn subject_entry<'a, N>(
&'a mut self,
subject: &QuadSubject<N>,
vocabulary: &N,
) -> indexmap::map::Entry<'a, String, Rc<RefCell<SubjectEntry>>>
where
N: Vocabulary,
{
self.subjects.entry(subject_string(subject, vocabulary))
}
pub(crate) fn remove_subject(&mut self, subject: &str) -> Option<Rc<RefCell<SubjectEntry>>> {
self.subjects.remove(subject)
}
pub(crate) fn object_entry<'a, N>(
&'a mut self,
object: &QuadSubject<N>,
vocabulary: &N,
) -> indexmap::map::Entry<'a, String, Rc<RefCell<ObjectEntry>>>
where
N: Vocabulary,
{
self.objects.entry(subject_string(object, vocabulary))
}
pub(crate) fn remove(&mut self, item: &str) {
self.subjects.remove(item);
self.objects.remove(item);
}
pub(crate) fn usages_entry(&mut self) -> &Rc<RefCell<Option<Vec<ReferencedValue>>>> {
*self.usages.borrow_mut() = Some(Vec::new());
&self.usages
}
pub(crate) fn usages(&self) -> &Rc<RefCell<Option<Vec<ReferencedValue>>>> {
&self.usages
}
pub(crate) fn to_vec(&self) -> Vec<(String, JsonValue)> {
let mut vec: Vec<(String, JsonValue)> = self
.graphs
.iter()
.map(|graph| {
let mut map = Map::new();
map.insert("@id".into(), graph.as_str().into());
(graph.into(), map.into())
})
.collect();
vec.extend(self.subjects.iter().map(|(subject, subject_entry)| {
(subject.clone(), subject_entry.borrow().to_json_value())
}));
vec.extend(
self.objects.iter().map(|(object, object_entry)| {
(object.clone(), object_entry.borrow().to_json_value())
}),
);
vec
}
}

View file

@ -0,0 +1,52 @@
use crate::rdf::{NormalizingQuad, QuadSubject, QuadValue};
use rdf_types::{Triple, Vocabulary};
use std::{collections::HashMap, hash::Hash};
type SerializingTriple<N> = Triple<QuadSubject<N>, QuadSubject<N>, QuadValue<N>>;
pub(crate) struct InputDataset<N>
where
N: Vocabulary,
{
graphs: HashMap<Option<QuadSubject<N>>, Vec<SerializingTriple<N>>>,
}
impl<N> Default for InputDataset<N>
where
N: Vocabulary,
{
fn default() -> Self {
Self {
graphs: Default::default(),
}
}
}
impl<N> InputDataset<N>
where
N: Vocabulary,
{
pub(crate) fn new(input_dataset: Vec<NormalizingQuad<N>>) -> Self
where
N::Iri: Hash + Eq,
N::BlankId: Hash + Eq,
{
input_dataset
.into_iter()
.fold(Self::default(), |mut this, quad| {
let (subject, predicate, object, graph) = quad.into_parts();
let triple = Triple(subject, predicate, object);
this.graphs.entry(graph).or_default().push(triple);
this
})
}
pub(crate) fn graphs(
&self,
) -> impl Iterator<Item = (Option<&'_ QuadSubject<N>>, &'_ [SerializingTriple<N>])> {
self.graphs.iter().map(|(k, v)| (k.as_ref(), v.as_slice()))
}
}

View file

@ -0,0 +1,225 @@
use crate::rdf::{get_subject, subject_str, QuadSubject};
use indexmap::IndexMap;
use locspan::Meta;
use rdf_types::Vocabulary;
use std::{
cell::{RefCell, RefMut},
rc::Rc,
};
pub(crate) fn subject_json<N>(id: &QuadSubject<N>, vocabulary: &N) -> JsonValue
where
N: Vocabulary,
{
let subject = get_subject(id, vocabulary);
let s = subject_str(&subject);
s.into()
}
pub(crate) type Map = IndexMap<String, JsonValue>;
pub(crate) type Array = Vec<JsonValue>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct JsonValue {
value: JsonValueKind,
}
#[derive(Clone, Debug, PartialEq, Eq)]
enum JsonValueKind {
Map(Rc<RefCell<Map>>),
Array(Rc<RefCell<Array>>),
String(json_syntax::String),
Number(json_syntax::NumberBuf),
Boolean(bool),
Null,
}
impl JsonValue {
pub(crate) fn matches_string(&self, s: &str) -> bool {
self.get_string().map(|string| string == s).unwrap_or(false)
}
pub(crate) fn get_string(&self) -> Option<&str> {
match self.value {
JsonValueKind::String(ref s) => Some(s.as_str()),
_ => None,
}
}
pub(crate) fn get_array_mut(&self) -> Option<RefMut<'_, Array>> {
match self.value {
JsonValueKind::Array(ref array) => Some(array.borrow_mut()),
_ => None,
}
}
pub(crate) fn get_map_mut(&self) -> Option<RefMut<'_, Map>> {
match self.value {
JsonValueKind::Map(ref map) => Some(map.borrow_mut()),
_ => None,
}
}
pub(crate) fn to_map(&self) -> Option<Rc<RefCell<Map>>> {
match self.value {
JsonValueKind::Map(ref map) => Some(map.clone()),
_ => None,
}
}
}
impl From<Map> for JsonValue {
fn from(value: Map) -> Self {
JsonValue {
value: JsonValueKind::Map(Rc::new(RefCell::new(value))),
}
}
}
impl From<Rc<RefCell<Map>>> for JsonValue {
fn from(value: Rc<RefCell<Map>>) -> Self {
JsonValue {
value: JsonValueKind::Map(value),
}
}
}
impl From<Array> for JsonValue {
fn from(value: Array) -> Self {
JsonValue {
value: JsonValueKind::Array(Rc::new(RefCell::new(value))),
}
}
}
impl From<Rc<RefCell<Array>>> for JsonValue {
fn from(value: Rc<RefCell<Array>>) -> Self {
JsonValue {
value: JsonValueKind::Array(value),
}
}
}
impl<'a> From<&'a str> for JsonValue {
fn from(value: &'a str) -> Self {
JsonValue {
value: JsonValueKind::String(value.into()),
}
}
}
impl From<json_syntax::String> for JsonValue {
fn from(value: json_syntax::String) -> Self {
JsonValue {
value: JsonValueKind::String(value),
}
}
}
impl From<json_syntax::NumberBuf> for JsonValue {
fn from(value: json_syntax::NumberBuf) -> Self {
JsonValue {
value: JsonValueKind::Number(value),
}
}
}
impl From<bool> for JsonValue {
fn from(value: bool) -> Self {
JsonValue {
value: JsonValueKind::Boolean(value),
}
}
}
impl From<()> for JsonValue {
fn from(_: ()) -> Self {
JsonValue {
value: JsonValueKind::Null,
}
}
}
impl<M> From<Meta<json_syntax::Value<M>, M>> for JsonValue {
fn from(Meta(value, _): Meta<json_syntax::Value<M>, M>) -> Self {
match value {
json_syntax::Value::Null => ().into(),
json_syntax::Value::Boolean(boolean) => boolean.into(),
json_syntax::Value::Number(num) => num.into(),
json_ld_syntax::Value::String(string) => string.into(),
json_ld_syntax::Value::Array(array) => array.into(),
json_ld_syntax::Value::Object(object) => object.into(),
}
}
}
pub(crate) struct WithMeta<M>(pub(crate) JsonValue, pub(crate) M);
impl<M> From<WithMeta<M>> for Meta<json_syntax::Value<M>, M>
where
M: Clone,
{
fn from(WithMeta(value, meta): WithMeta<M>) -> Self {
let value = match value.value {
JsonValueKind::Null => json_syntax::Value::Null,
JsonValueKind::Boolean(boolean) => json_syntax::Value::Boolean(boolean),
JsonValueKind::Number(number) => json_syntax::Value::Number(number),
JsonValueKind::String(string) => json_syntax::Value::String(string),
JsonValueKind::Array(array) => json_syntax::Value::Array(
array
.borrow()
.iter()
.map(|value| WithMeta(value.clone(), meta.clone()).into())
.collect(),
),
JsonValueKind::Map(map) => json_syntax::Value::Object(map.borrow().iter().fold(
json_syntax::Object::new(),
|mut object, (k, v)| {
object.insert(
Meta(k.as_str().into(), meta.clone()),
WithMeta(v.clone(), meta.clone()).into(),
);
object
},
)),
};
Meta(value, meta)
}
}
impl<M> From<json_syntax::Array<M>> for JsonValue {
fn from(values: json_syntax::Array<M>) -> Self {
let array = values
.into_iter()
.map(|value| value.into())
.collect::<Vec<JsonValue>>();
array.into()
}
}
impl<M> From<json_syntax::Object<M>> for JsonValue {
fn from(value: json_syntax::Object<M>) -> Self {
let mut map = Map::new();
for json_syntax::object::Entry { key, value } in value.into_iter() {
if let Some(entry) = map.remove(key.0.as_str()) {
let entry_clone = entry.clone();
let entry = if let Some(mut array) = entry.get_array_mut() {
array.push(value.into());
drop(array);
entry_clone
} else {
vec![entry_clone, value.into()].into()
};
map.insert(key.0.to_string(), entry);
} else {
map.insert(key.0.to_string(), value.into());
}
}
map.into()
}
}

View file

@ -1,5 +1,3 @@
use indexmap::{IndexMap, IndexSet};
use iref::Iri;
use json_ld::{
rdf::{
RdfDirection, RDF_DIRECTION, RDF_FIRST, RDF_JSON, RDF_NIL, RDF_REST, RDF_TYPE, RDF_VALUE,
@ -9,762 +7,41 @@ use json_ld::{
};
use json_ld_syntax::Parse;
use locspan::Meta;
use rdf_types::{BlankId, BlankIdVocabulary, IriVocabulary, Quad, Triple, Vocabulary};
use rdf_types::Vocabulary;
use smallvec::SmallVec;
use static_iref::iri;
use std::{
cell::{RefCell, RefMut},
collections::HashMap,
hash::Hash,
rc::Rc,
use std::{cell::RefCell, hash::Hash, rc::Rc};
mod compound_literal_subjects;
mod graph_map;
mod input_dataset;
mod json_value;
mod object_entry;
mod rdf;
mod referenced_once;
mod subject_entry;
use compound_literal_subjects::CompoundLiteralSubjects;
use graph_map::{GraphEntry, GraphMap};
use input_dataset::InputDataset;
use json_value::{subject_json, Array, JsonValue, Map, WithMeta};
use object_entry::ObjectEntry;
use rdf::{
expect_iri, get_iri, subject_matches, subject_string, NormalizingQuad, QuadValue, RDF_LANGUAGE,
RDF_LIST,
};
const RDF_LANGUAGE: Iri<'static> = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#language");
const RDF_LIST: Iri<'static> = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#list");
type QuadSubject<N> = Subject<<N as IriVocabulary>::Iri, <N as BlankIdVocabulary>::BlankId>;
type QuadValue<N> =
json_ld::rdf::Value<<N as IriVocabulary>::Iri, <N as BlankIdVocabulary>::BlankId>;
type NormalizingQuad<N> = Quad<QuadSubject<N>, QuadSubject<N>, QuadValue<N>, QuadSubject<N>>;
type SerializingTriple<N> = Triple<QuadSubject<N>, QuadSubject<N>, QuadValue<N>>;
struct InputDataset<N>
where
N: Vocabulary,
{
graphs: HashMap<Option<QuadSubject<N>>, Vec<SerializingTriple<N>>>,
}
impl<N> Default for InputDataset<N>
where
N: Vocabulary,
{
fn default() -> Self {
Self {
graphs: Default::default(),
}
}
}
impl<N> InputDataset<N>
where
N: Vocabulary,
{
fn new(input_dataset: Vec<NormalizingQuad<N>>) -> Self
where
N::Iri: Hash + Eq,
N::BlankId: Hash + Eq,
{
input_dataset
.into_iter()
.fold(Self::default(), |mut this, quad| {
let (subject, predicate, object, graph) = quad.into_parts();
let triple = Triple(subject, predicate, object);
this.graphs.entry(graph).or_default().push(triple);
this
})
}
fn graphs(
&self,
) -> impl Iterator<Item = (Option<&'_ QuadSubject<N>>, &'_ [SerializingTriple<N>])> {
self.graphs.iter().map(|(k, v)| (k.as_ref(), v.as_slice()))
}
}
fn expect_iri<N>(id: &N::Iri, iri: Iri<'_>, vocabulary: &N) -> bool
where
N: Vocabulary,
N::Iri: Eq,
{
vocabulary.get(iri).map(|iri| iri == *id).unwrap_or(false) || get_iri(id, vocabulary) == iri
}
fn get_iri<'a, N>(id: &'a N::Iri, vocabulary: &'a N) -> Iri<'a>
where
N: Vocabulary,
{
vocabulary.iri(id).expect("Id in vocabulary")
}
fn get_subject<'a, N>(id: &'a QuadSubject<N>, vocabulary: &'a N) -> Subject<Iri<'a>, &'a BlankId>
where
N: Vocabulary,
{
match id {
Subject::Iri(iri) => Subject::Iri(vocabulary.iri(iri).expect("Id in vocabulary")),
Subject::Blank(blank) => {
Subject::Blank(vocabulary.blank_id(blank).expect("Id in vocabulary"))
}
}
}
fn subject_str<'a>(subject: &'a Subject<Iri<'a>, &'a BlankId>) -> &'a str {
match subject {
Subject::Iri(ref iri) => iri.as_str(),
Subject::Blank(blank) => blank.as_str(),
}
}
fn subject_matches<N>(subject: &Subject<N::Iri, N::BlankId>, iri: Iri<'_>, vocabulary: &N) -> bool
where
N: Vocabulary,
N::Iri: Eq,
{
match subject {
Subject::Iri(id) => expect_iri(id, iri, vocabulary),
Subject::Blank(_) => false,
}
}
fn subject_string<N>(id: &Subject<N::Iri, N::BlankId>, vocabulary: &N) -> String
where
N: Vocabulary,
{
let subject = get_subject(id, vocabulary);
let s = subject_str(&subject);
s.to_string()
}
fn subject_json<N>(id: &Subject<N::Iri, N::BlankId>, vocabulary: &N) -> JsonValue
where
N: Vocabulary,
{
let subject = get_subject(id, vocabulary);
let s = subject_str(&subject);
s.into()
}
#[derive(Clone, Debug, PartialEq, Eq)]
struct JsonValue {
value: JsonValueKind,
}
impl JsonValue {
fn matches_string(&self, s: &str) -> bool {
self.get_string().map(|string| string == s).unwrap_or(false)
}
fn get_string(&self) -> Option<&str> {
match self.value {
JsonValueKind::String(ref s) => Some(s.as_str()),
_ => None,
}
}
fn get_array_mut(&self) -> Option<RefMut<'_, Array>> {
match self.value {
JsonValueKind::Array(ref array) => Some(array.borrow_mut()),
_ => None,
}
}
fn get_map_mut(&self) -> Option<RefMut<'_, Map>> {
match self.value {
JsonValueKind::Map(ref map) => Some(map.borrow_mut()),
_ => None,
}
}
fn to_map(&self) -> Option<Rc<RefCell<Map>>> {
match self.value {
JsonValueKind::Map(ref map) => Some(map.clone()),
_ => None,
}
}
}
type Map = IndexMap<String, JsonValue>;
type Array = Vec<JsonValue>;
#[derive(Clone, Debug, PartialEq, Eq)]
enum JsonValueKind {
Map(Rc<RefCell<Map>>),
Array(Rc<RefCell<Array>>),
String(json_syntax::String),
Number(json_syntax::NumberBuf),
Boolean(bool),
Null,
}
impl From<Map> for JsonValue {
fn from(value: Map) -> Self {
JsonValue {
value: JsonValueKind::Map(Rc::new(RefCell::new(value))),
}
}
}
impl From<Rc<RefCell<Map>>> for JsonValue {
fn from(value: Rc<RefCell<Map>>) -> Self {
JsonValue {
value: JsonValueKind::Map(value),
}
}
}
impl From<Array> for JsonValue {
fn from(value: Array) -> Self {
JsonValue {
value: JsonValueKind::Array(Rc::new(RefCell::new(value))),
}
}
}
impl From<Rc<RefCell<Array>>> for JsonValue {
fn from(value: Rc<RefCell<Array>>) -> Self {
JsonValue {
value: JsonValueKind::Array(value),
}
}
}
impl<'a> From<&'a str> for JsonValue {
fn from(value: &'a str) -> Self {
JsonValue {
value: JsonValueKind::String(value.into()),
}
}
}
impl From<json_syntax::String> for JsonValue {
fn from(value: json_syntax::String) -> Self {
JsonValue {
value: JsonValueKind::String(value),
}
}
}
impl From<json_syntax::NumberBuf> for JsonValue {
fn from(value: json_syntax::NumberBuf) -> Self {
JsonValue {
value: JsonValueKind::Number(value),
}
}
}
impl From<bool> for JsonValue {
fn from(value: bool) -> Self {
JsonValue {
value: JsonValueKind::Boolean(value),
}
}
}
impl From<()> for JsonValue {
fn from(_: ()) -> Self {
JsonValue {
value: JsonValueKind::Null,
}
}
}
impl<M> From<Meta<json_syntax::Value<M>, M>> for JsonValue {
fn from(Meta(value, _): Meta<json_syntax::Value<M>, M>) -> Self {
match value {
json_syntax::Value::Null => ().into(),
json_syntax::Value::Boolean(boolean) => boolean.into(),
json_syntax::Value::Number(num) => num.into(),
json_ld_syntax::Value::String(string) => string.into(),
json_ld_syntax::Value::Array(array) => array.into(),
json_ld_syntax::Value::Object(object) => object.into(),
}
}
}
struct WithMeta<M>(JsonValue, M);
impl<M> From<WithMeta<M>> for Meta<json_syntax::Value<M>, M>
where
M: Clone,
{
fn from(WithMeta(value, meta): WithMeta<M>) -> Self {
let value = match value.value {
JsonValueKind::Null => json_syntax::Value::Null,
JsonValueKind::Boolean(boolean) => json_syntax::Value::Boolean(boolean),
JsonValueKind::Number(number) => json_syntax::Value::Number(number),
JsonValueKind::String(string) => json_syntax::Value::String(string),
JsonValueKind::Array(array) => json_syntax::Value::Array(
array
.borrow()
.iter()
.map(|value| WithMeta(value.clone(), meta.clone()).into())
.collect(),
),
JsonValueKind::Map(map) => json_syntax::Value::Object(map.borrow().iter().fold(
json_syntax::Object::new(),
|mut object, (k, v)| {
object.insert(
Meta(k.as_str().into(), meta.clone()),
WithMeta(v.clone(), meta.clone()).into(),
);
object
},
)),
};
Meta(value, meta)
}
}
impl<M> From<json_syntax::Array<M>> for JsonValue {
fn from(values: json_syntax::Array<M>) -> Self {
let array = values
.into_iter()
.map(|value| value.into())
.collect::<Vec<JsonValue>>();
array.into()
}
}
impl<M> From<json_syntax::Object<M>> for JsonValue {
fn from(value: json_syntax::Object<M>) -> Self {
let mut map = Map::new();
for json_syntax::object::Entry { key, value } in value.into_iter() {
if let Some(entry) = map.remove(key.0.as_str()) {
let entry_clone = entry.clone();
let entry = if let Some(mut array) = entry.get_array_mut() {
array.push(value.into());
drop(array);
entry_clone
} else {
vec![entry_clone, value.into()].into()
};
map.insert(key.0.to_string(), entry);
} else {
map.insert(key.0.to_string(), value.into());
}
}
map.into()
}
}
use referenced_once::{ReferencedOnce, ReferencedValue};
use subject_entry::SubjectEntry;
#[derive(Debug)]
pub struct InvalidJson;
#[derive(Debug, Default)]
struct ReferencedOnce {
value: HashMap<String, ReferencedEntry>,
}
impl ReferencedOnce {
fn new() -> Self {
Self::default()
}
fn get_mut<'a>(&'a mut self, object: &str) -> Option<&'a mut ReferencedEntry> {
self.value.get_mut(object)
}
fn get_value(&self, object: &str) -> Option<&ReferencedValue> {
self.value.get(object).and_then(|entry| match entry {
ReferencedEntry::False => None,
ReferencedEntry::Value(value) => Some(value),
})
}
fn contains_key(&self, object: &str) -> bool {
self.get_value(object).is_some()
}
fn insert(&mut self, object: String, referenced_value: ReferencedValue) {
self.value
.insert(object, ReferencedEntry::Value(referenced_value));
impl std::fmt::Display for InvalidJson {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Invalid Json")
}
}
#[derive(Debug)]
enum ReferencedEntry {
False,
Value(ReferencedValue),
}
#[derive(Debug, Clone)]
struct ReferencedValue {
node: Rc<RefCell<SubjectEntry>>,
property: String,
value: Rc<RefCell<Map>>,
}
impl ReferencedEntry {
fn set_false(&mut self) {
*self = Self::False;
}
}
impl ReferencedValue {
fn new<N>(
node: Rc<RefCell<SubjectEntry>>,
property: &Subject<N::Iri, N::BlankId>,
value: Rc<RefCell<Map>>,
vocabulary: &N,
) -> Self
where
N: Vocabulary,
{
let property = get_subject(property, vocabulary);
let property = subject_str(&property).to_string();
Self {
node,
property,
value,
}
}
}
#[derive(Default)]
struct GraphMap {
graphs: IndexMap<String, Rc<RefCell<GraphEntry>>>,
}
impl GraphMap {
fn insert(&mut self, graph_name: String, graph_entry: Rc<RefCell<GraphEntry>>) {
self.graphs.insert(graph_name, graph_entry);
}
fn entry(
&mut self,
graph_name: String,
) -> indexmap::map::Entry<'_, String, Rc<RefCell<GraphEntry>>> {
self.graphs.entry(graph_name)
}
fn iter(&self) -> indexmap::map::Iter<'_, String, Rc<RefCell<GraphEntry>>> {
self.graphs.iter()
}
fn get(&self, graph: &str) -> Option<&Rc<RefCell<GraphEntry>>> {
self.graphs.get(graph)
}
}
#[derive(Default)]
struct GraphEntry {
// short for
// {graph_name} -> Map
// @id -> {graph_name}
graphs: IndexSet<String>,
// short for
// {subject} -> Map
// @id -> {subject}
// @type -> Array
// {object}
// {predicate} -> Array
// {object}
subjects: IndexMap<String, Rc<RefCell<SubjectEntry>>>,
// short for
// {object} -> Map
// @id -> {object}
// short for
// {object} -> Map
// @id -> {object}
objects: IndexMap<String, Rc<RefCell<ObjectEntry>>>,
// short for
// nil -> Map
// usages -> Array
// node -> Map (SubjectEntry)
// property -> {predicate}
// value -> {object}
usages: Rc<RefCell<Option<Vec<ReferencedValue>>>>,
}
impl GraphEntry {
fn contains_graph(&self, graph_name: &str) -> bool {
self.graphs.contains(graph_name)
}
fn insert_graph(&mut self, graph_name: String) {
self.graphs.insert(graph_name);
}
fn subject_entry<'a, N>(
&'a mut self,
subject: &Subject<N::Iri, N::BlankId>,
vocabulary: &N,
) -> indexmap::map::Entry<'a, String, Rc<RefCell<SubjectEntry>>>
where
N: Vocabulary,
{
self.subjects.entry(subject_string(subject, vocabulary))
}
fn remove_subject(&mut self, subject: &str) -> Option<Rc<RefCell<SubjectEntry>>> {
self.subjects.remove(subject)
}
fn object_entry<'a, N>(
&'a mut self,
object: &Subject<N::Iri, N::BlankId>,
vocabulary: &N,
) -> indexmap::map::Entry<'a, String, Rc<RefCell<ObjectEntry>>>
where
N: Vocabulary,
{
self.objects.entry(subject_string(object, vocabulary))
}
fn remove(&mut self, item: &str) {
self.subjects.remove(item);
self.objects.remove(item);
}
fn usages_entry(&mut self) -> &Rc<RefCell<Option<Vec<ReferencedValue>>>> {
*self.usages.borrow_mut() = Some(Vec::new());
&self.usages
}
fn usages(&self) -> &Rc<RefCell<Option<Vec<ReferencedValue>>>> {
&self.usages
}
fn to_vec(&self) -> Vec<(String, JsonValue)> {
let mut vec: Vec<(String, JsonValue)> = self
.graphs
.iter()
.map(|graph| {
let mut map = Map::new();
map.insert("@id".into(), graph.as_str().into());
(graph.into(), map.into())
})
.collect();
vec.extend(self.subjects.iter().map(|(subject, subject_entry)| {
(subject.clone(), subject_entry.borrow().to_json_value())
}));
vec.extend(
self.objects.iter().map(|(object, object_entry)| {
(object.clone(), object_entry.borrow().to_json_value())
}),
);
vec
}
}
#[derive(Debug)]
struct SubjectEntry {
// @id -> {subject}
id: json_syntax::String,
// @type -> Array
// {object} (if type)
ty: Option<Vec<json_syntax::String>>,
// {predicate} -> Array
// {object} (value)
predicate_values: IndexMap<String, Vec<Rc<RefCell<Map>>>>,
}
impl SubjectEntry {
fn new<N>(subject: &Subject<N::Iri, N::BlankId>, vocabulary: &N) -> Self
where
N: Vocabulary,
{
let subject = get_subject(subject, vocabulary);
let subject_str = subject_str(&subject);
SubjectEntry {
id: subject_str.into(),
ty: None,
predicate_values: Default::default(),
}
}
fn contains_type<N>(&self, rhs: &Subject<N::Iri, N::BlankId>, vocabulary: &N) -> bool
where
N: Vocabulary,
{
let rhs = get_subject(rhs, vocabulary);
let rhs_str = subject_str(&rhs);
if let Some(ty) = &self.ty {
ty.iter().any(|lhs| lhs.as_str() == rhs_str)
} else {
false
}
}
fn insert_type<N>(&mut self, ty: &Subject<N::Iri, N::BlankId>, vocabulary: &N)
where
N: Vocabulary,
{
let ty = get_subject(ty, vocabulary);
let ty_str = subject_str(&ty);
if let Some(ty) = &mut self.ty {
ty.push(ty_str.into());
} else {
self.ty = Some(vec![ty_str.into()]);
}
}
fn predicate_entry<'a, N>(
&'a mut self,
predicate: &Subject<N::Iri, N::BlankId>,
vocabulary: &N,
) -> indexmap::map::Entry<'a, String, Vec<Rc<RefCell<Map>>>>
where
N: Vocabulary,
{
self.predicate_values
.entry(subject_string(predicate, vocabulary))
}
fn contains_predicate_value<N>(
&self,
predicate: &Subject<N::Iri, N::BlankId>,
vocabulary: &N,
rhs: &Rc<RefCell<Map>>,
) -> bool
where
N: Vocabulary,
{
let predicate = get_subject(predicate, vocabulary);
let predicate_str = subject_str(&predicate);
let Some(values) = self.predicate_values.get(predicate_str) else { return false; };
values.iter().any(|lhs| *lhs.borrow() == *rhs.borrow())
}
fn insert_predicate_value<N>(
&mut self,
predicate: &Subject<N::Iri, N::BlankId>,
vocabulary: &N,
value: Rc<RefCell<Map>>,
) where
N: Vocabulary,
{
let predicate = get_subject(predicate, vocabulary);
let predicate_str = subject_str(&predicate);
let Some(values) = self.predicate_values.get_mut(predicate_str) else { return; };
values.push(value);
}
fn predicate_value(&self, predicate: &str) -> Option<&Vec<Rc<RefCell<Map>>>> {
self.predicate_values.get(predicate)
}
fn is_blank_node(&self) -> bool {
self.id.starts_with("_:")
}
fn id(&self) -> &str {
self.id.as_str()
}
fn ty(&self) -> Option<&[json_syntax::String]> {
self.ty.as_deref()
}
fn predicate_len(&self) -> usize {
self.predicate_values.len()
}
fn to_json_value(&self) -> JsonValue {
let mut map = Map::new();
map.insert("@id".into(), self.id.clone().into());
if let Some(ty) = &self.ty {
map.insert(
"@type".into(),
ty.iter()
.map(|ty| ty.as_str().into())
.collect::<Vec<JsonValue>>()
.into(),
);
}
for (predicate, values) in &self.predicate_values {
map.insert(
predicate.into(),
values
.iter()
.map(|value| value.clone().into())
.collect::<Vec<JsonValue>>()
.into(),
);
}
map.into()
}
}
struct ObjectEntry {
// short for
// @id -> rdf:nil
id: json_syntax::String,
}
impl ObjectEntry {
fn new<N>(object: &Subject<N::Iri, N::BlankId>, vocabulary: &N) -> Self
where
N: Vocabulary,
{
let object = get_subject(object, vocabulary);
let object_str = subject_str(&object);
ObjectEntry {
id: object_str.into(),
}
}
fn to_json_value(&self) -> JsonValue {
let mut map = Map::new();
map.insert("@id".into(), self.id.clone().into());
map.into()
}
}
#[derive(Default)]
struct CompoundLiteralSubjects {
graphs: IndexMap<String, CompoundMap>,
}
impl CompoundLiteralSubjects {
fn graph_entry(&mut self, graph: String) -> indexmap::map::Entry<'_, String, CompoundMap> {
self.graphs.entry(graph)
}
fn graph(&self, graph: &str) -> Option<&CompoundMap> {
self.graphs.get(graph)
}
}
#[derive(Default)]
struct CompoundMap {
subjects: IndexSet<String>,
}
impl CompoundMap {
fn insert<N>(&mut self, subject: &Subject<N::Iri, N::BlankId>, vocabulary: &N)
where
N: Vocabulary,
{
let subject = subject_string(subject, vocabulary);
self.subjects.insert(subject);
}
fn iter(&self) -> indexmap::set::Iter<'_, String> {
self.subjects.iter()
}
}
impl std::error::Error for InvalidJson {}
pub fn rdf_to_json_ld<N, M>(
rdf_dataset: Vec<NormalizingQuad<N>>,

View file

@ -0,0 +1,31 @@
use crate::{
json_value::{JsonValue, Map},
rdf::{get_subject, subject_str, QuadSubject},
};
use rdf_types::Vocabulary;
pub(crate) struct ObjectEntry {
// short for
// @id -> rdf:nil
id: json_syntax::String,
}
impl ObjectEntry {
pub(crate) fn new<N>(object: &QuadSubject<N>, vocabulary: &N) -> Self
where
N: Vocabulary,
{
let object = get_subject(object, vocabulary);
let object_str = subject_str(&object);
ObjectEntry {
id: object_str.into(),
}
}
pub(crate) fn to_json_value(&self) -> JsonValue {
let mut map = Map::new();
map.insert("@id".into(), self.id.clone().into());
map.into()
}
}

74
serialization/src/rdf.rs Normal file
View file

@ -0,0 +1,74 @@
use iref::Iri;
use json_ld::ValidId as Subject;
use rdf_types::{BlankId, BlankIdVocabulary, IriVocabulary, Quad, Vocabulary};
use static_iref::iri;
pub(crate) const RDF_LANGUAGE: Iri<'static> =
iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#language");
pub(crate) const RDF_LIST: Iri<'static> = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#list");
pub(crate) type QuadSubject<N> =
Subject<<N as IriVocabulary>::Iri, <N as BlankIdVocabulary>::BlankId>;
pub(crate) type QuadValue<N> =
json_ld::rdf::Value<<N as IriVocabulary>::Iri, <N as BlankIdVocabulary>::BlankId>;
pub(crate) type NormalizingQuad<N> =
Quad<QuadSubject<N>, QuadSubject<N>, QuadValue<N>, QuadSubject<N>>;
pub(crate) fn expect_iri<N>(id: &N::Iri, iri: Iri<'_>, vocabulary: &N) -> bool
where
N: Vocabulary,
N::Iri: Eq,
{
vocabulary.get(iri).map(|iri| iri == *id).unwrap_or(false) || get_iri(id, vocabulary) == iri
}
pub(crate) fn get_iri<'a, N>(id: &'a N::Iri, vocabulary: &'a N) -> Iri<'a>
where
N: Vocabulary,
{
vocabulary.iri(id).expect("Id in vocabulary")
}
pub(crate) fn get_subject<'a, N>(
id: &'a QuadSubject<N>,
vocabulary: &'a N,
) -> Subject<Iri<'a>, &'a BlankId>
where
N: Vocabulary,
{
match id {
Subject::Iri(iri) => Subject::Iri(vocabulary.iri(iri).expect("Id in vocabulary")),
Subject::Blank(blank) => {
Subject::Blank(vocabulary.blank_id(blank).expect("Id in vocabulary"))
}
}
}
pub(crate) fn subject_str<'a>(subject: &'a Subject<Iri<'a>, &'a BlankId>) -> &'a str {
match subject {
Subject::Iri(ref iri) => iri.as_str(),
Subject::Blank(blank) => blank.as_str(),
}
}
pub(crate) fn subject_matches<N>(subject: &QuadSubject<N>, iri: Iri<'_>, vocabulary: &N) -> bool
where
N: Vocabulary,
N::Iri: Eq,
{
match subject {
Subject::Iri(id) => expect_iri(id, iri, vocabulary),
Subject::Blank(_) => false,
}
}
pub(crate) fn subject_string<N>(id: &QuadSubject<N>, vocabulary: &N) -> String
where
N: Vocabulary,
{
let subject = get_subject(id, vocabulary);
let s = subject_str(&subject);
s.to_string()
}

View file

@ -0,0 +1,78 @@
use crate::{
json_value::Map,
rdf::{get_subject, subject_str, QuadSubject},
subject_entry::SubjectEntry,
};
use rdf_types::Vocabulary;
use std::{cell::RefCell, collections::HashMap, rc::Rc};
#[derive(Debug, Default)]
pub(crate) struct ReferencedOnce {
value: HashMap<String, ReferencedEntry>,
}
#[derive(Debug)]
pub(crate) enum ReferencedEntry {
False,
Value(ReferencedValue),
}
#[derive(Debug, Clone)]
pub(crate) struct ReferencedValue {
pub(crate) node: Rc<RefCell<SubjectEntry>>,
pub(crate) property: String,
pub(crate) value: Rc<RefCell<Map>>,
}
impl ReferencedOnce {
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn get_mut<'a>(&'a mut self, object: &str) -> Option<&'a mut ReferencedEntry> {
self.value.get_mut(object)
}
pub(crate) fn get_value(&self, object: &str) -> Option<&ReferencedValue> {
self.value.get(object).and_then(|entry| match entry {
ReferencedEntry::False => None,
ReferencedEntry::Value(value) => Some(value),
})
}
pub(crate) fn contains_key(&self, object: &str) -> bool {
self.get_value(object).is_some()
}
pub(crate) fn insert(&mut self, object: String, referenced_value: ReferencedValue) {
self.value
.insert(object, ReferencedEntry::Value(referenced_value));
}
}
impl ReferencedEntry {
pub(crate) fn set_false(&mut self) {
*self = Self::False;
}
}
impl ReferencedValue {
pub(crate) fn new<N>(
node: Rc<RefCell<SubjectEntry>>,
property: &QuadSubject<N>,
value: Rc<RefCell<Map>>,
vocabulary: &N,
) -> Self
where
N: Vocabulary,
{
let property = get_subject(property, vocabulary);
let property = subject_str(&property).to_string();
Self {
node,
property,
value,
}
}
}

View file

@ -0,0 +1,157 @@
use crate::{
json_value::{JsonValue, Map},
rdf::{get_subject, subject_str, subject_string, QuadSubject},
};
use indexmap::IndexMap;
use rdf_types::Vocabulary;
use std::{cell::RefCell, rc::Rc};
#[derive(Debug)]
pub(crate) struct SubjectEntry {
// @id -> {subject}
id: json_syntax::String,
// @type -> Array
// {object} (if type)
ty: Option<Vec<json_syntax::String>>,
// {predicate} -> Array
// {object} (value)
predicate_values: IndexMap<String, Vec<Rc<RefCell<Map>>>>,
}
impl SubjectEntry {
pub(crate) fn new<N>(subject: &QuadSubject<N>, vocabulary: &N) -> Self
where
N: Vocabulary,
{
let subject = get_subject(subject, vocabulary);
let subject_str = subject_str(&subject);
SubjectEntry {
id: subject_str.into(),
ty: None,
predicate_values: Default::default(),
}
}
pub(crate) fn contains_type<N>(&self, rhs: &QuadSubject<N>, vocabulary: &N) -> bool
where
N: Vocabulary,
{
let rhs = get_subject(rhs, vocabulary);
let rhs_str = subject_str(&rhs);
if let Some(ty) = &self.ty {
ty.iter().any(|lhs| lhs.as_str() == rhs_str)
} else {
false
}
}
pub(crate) fn insert_type<N>(&mut self, ty: &QuadSubject<N>, vocabulary: &N)
where
N: Vocabulary,
{
let ty = get_subject(ty, vocabulary);
let ty_str = subject_str(&ty);
if let Some(ty) = &mut self.ty {
ty.push(ty_str.into());
} else {
self.ty = Some(vec![ty_str.into()]);
}
}
pub(crate) fn predicate_entry<'a, N>(
&'a mut self,
predicate: &QuadSubject<N>,
vocabulary: &N,
) -> indexmap::map::Entry<'a, String, Vec<Rc<RefCell<Map>>>>
where
N: Vocabulary,
{
self.predicate_values
.entry(subject_string(predicate, vocabulary))
}
pub(crate) fn contains_predicate_value<N>(
&self,
predicate: &QuadSubject<N>,
vocabulary: &N,
rhs: &Rc<RefCell<Map>>,
) -> bool
where
N: Vocabulary,
{
let predicate = get_subject(predicate, vocabulary);
let predicate_str = subject_str(&predicate);
let Some(values) = self.predicate_values.get(predicate_str) else { return false; };
values.iter().any(|lhs| *lhs.borrow() == *rhs.borrow())
}
pub(crate) fn insert_predicate_value<N>(
&mut self,
predicate: &QuadSubject<N>,
vocabulary: &N,
value: Rc<RefCell<Map>>,
) where
N: Vocabulary,
{
let predicate = get_subject(predicate, vocabulary);
let predicate_str = subject_str(&predicate);
let Some(values) = self.predicate_values.get_mut(predicate_str) else { return; };
values.push(value);
}
pub(crate) fn predicate_value(&self, predicate: &str) -> Option<&Vec<Rc<RefCell<Map>>>> {
self.predicate_values.get(predicate)
}
pub(crate) fn is_blank_node(&self) -> bool {
self.id.starts_with("_:")
}
pub(crate) fn id(&self) -> &str {
self.id.as_str()
}
pub(crate) fn ty(&self) -> Option<&[json_syntax::String]> {
self.ty.as_deref()
}
pub(crate) fn predicate_len(&self) -> usize {
self.predicate_values.len()
}
pub(crate) fn to_json_value(&self) -> JsonValue {
let mut map = Map::new();
map.insert("@id".into(), self.id.clone().into());
if let Some(ty) = &self.ty {
map.insert(
"@type".into(),
ty.iter()
.map(|ty| ty.as_str().into())
.collect::<Vec<JsonValue>>()
.into(),
);
}
for (predicate, values) in &self.predicate_values {
map.insert(
predicate.into(),
values
.iter()
.map(|value| value.clone().into())
.collect::<Vec<JsonValue>>()
.into(),
);
}
map.into()
}
}