From 2afead7be57784bfddc69d16db6e1592686d2e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Haudebourg?= Date: Fri, 22 Mar 2024 11:47:47 +0100 Subject: [PATCH] Move main package to workspace's toplevel. Bump `rdf-types` to version 0.22.0 Update `README.md` (add badges) Add CI workflow. --- .github/workflows/ci.yml | 50 +++ Cargo.toml | 41 ++- README.md | 28 +- cliff.toml | 60 ++++ {linked-data-derive => derive}/Cargo.toml | 0 {linked-data-derive => derive}/README.md | 0 .../src/generate.rs | 4 +- .../src/generate/de.rs | 2 +- .../src/generate/de/enum.rs | 23 +- .../src/generate/de/struct.rs | 8 +- .../src/generate/ser.rs | 0 .../src/generate/ser/enum.rs | 0 .../src/generate/ser/struct.rs | 0 {linked-data-derive => derive}/src/lib.rs | 0 {linked-data-derive => derive}/src/utils.rs | 0 {linked-data/examples => examples}/derive.rs | 0 .../examples => examples}/derive_enum.rs | 0 .../examples => examples}/generics.rs | 0 {linked-data/examples => examples}/graph.rs | 0 linked-data/Cargo.toml | 28 -- linked-data/README.md | 48 --- linked-data/src/impl.rs | 1 - linked-data/src/impl/grdf.rs | 2 - linked-data/src/impl/grdf/graph_view.rs | 186 ---------- linked-data/src/impl/grdf/view.rs | 317 ---------------- {linked-data/src => src}/anonymous.rs | 2 +- {linked-data/src => src}/datatypes/de.rs | 33 +- .../src/datatypes.rs => src/datatypes/mod.rs | 0 {linked-data/src => src}/datatypes/ser.rs | 41 +-- {linked-data/src => src}/graph.rs | 0 src/impl/mod.rs | 1 + src/impl/rdf_types/dataset_graph_view.rs | 193 ++++++++++ src/impl/rdf_types/dataset_view.rs | 337 ++++++++++++++++++ src/impl/rdf_types/mod.rs | 2 + {linked-data/src => src}/lib.rs | 28 +- {linked-data/src => src}/macros.rs | 38 +- {linked-data/src => src}/predicate.rs | 54 +-- {linked-data/src => src}/quads.rs | 87 ++--- {linked-data/src => src}/rdf.rs | 174 ++++----- {linked-data/src => src}/reference.rs | 0 {linked-data/src => src}/resource.rs | 33 +- {linked-data/src => src}/subject.rs | 61 +--- 42 files changed, 912 insertions(+), 970 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 cliff.toml rename {linked-data-derive => derive}/Cargo.toml (100%) rename {linked-data-derive => derive}/README.md (100%) rename {linked-data-derive => derive}/src/generate.rs (98%) rename {linked-data-derive => derive}/src/generate/de.rs (97%) rename {linked-data-derive => derive}/src/generate/de/enum.rs (90%) rename {linked-data-derive => derive}/src/generate/de/struct.rs (88%) rename {linked-data-derive => derive}/src/generate/ser.rs (100%) rename {linked-data-derive => derive}/src/generate/ser/enum.rs (100%) rename {linked-data-derive => derive}/src/generate/ser/struct.rs (100%) rename {linked-data-derive => derive}/src/lib.rs (100%) rename {linked-data-derive => derive}/src/utils.rs (100%) rename {linked-data/examples => examples}/derive.rs (100%) rename {linked-data/examples => examples}/derive_enum.rs (100%) rename {linked-data/examples => examples}/generics.rs (100%) rename {linked-data/examples => examples}/graph.rs (100%) delete mode 100644 linked-data/Cargo.toml delete mode 100644 linked-data/README.md delete mode 100644 linked-data/src/impl.rs delete mode 100644 linked-data/src/impl/grdf.rs delete mode 100644 linked-data/src/impl/grdf/graph_view.rs delete mode 100644 linked-data/src/impl/grdf/view.rs rename {linked-data/src => src}/anonymous.rs (96%) rename {linked-data/src => src}/datatypes/de.rs (72%) rename linked-data/src/datatypes.rs => src/datatypes/mod.rs (100%) rename {linked-data/src => src}/datatypes/ser.rs (81%) rename {linked-data/src => src}/graph.rs (100%) create mode 100644 src/impl/mod.rs create mode 100644 src/impl/rdf_types/dataset_graph_view.rs create mode 100644 src/impl/rdf_types/dataset_view.rs create mode 100644 src/impl/rdf_types/mod.rs rename {linked-data/src => src}/lib.rs (95%) rename {linked-data/src => src}/macros.rs (76%) rename {linked-data/src => src}/predicate.rs (88%) rename {linked-data/src => src}/quads.rs (92%) rename {linked-data/src => src}/rdf.rs (56%) rename {linked-data/src => src}/reference.rs (100%) rename {linked-data/src => src}/resource.rs (84%) rename {linked-data/src => src}/subject.rs (87%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d35e199 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,50 @@ +name: Continuous Integration + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +env: + CARGO_TERM_COLORS: always + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Retrieve MSRV + id: msrv + run: echo "MSRV=$(cat Cargo.toml | grep -Po '(?<=rust-version = ")([\d\.]+)')" >> $GITHUB_OUTPUT + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ steps.msrv.outputs.MSRV }} + - name: Build + run: cargo build --all-features --verbose + - name: Run tests + run: cargo test --all-features --verbose + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: Check formatting + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + - name: Clippy + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --all-features -- -D warnings \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index af63359..ce299e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,47 @@ +[package] +name = "linked-data" +authors = ["Spruce Systems, Inc."] +license = "MIT/Apache-2.0" +description = "Linked-Data dateset serialization/deserialization traits" +categories = ["encoding", "web-programming"] +keywords = ["semantic-web", "linked-data", "rdf", "serialization"] +repository = "https://github.com/spruceid/linked-data-rs" +edition = "2021" +rust-version = "1.71.1" +version = "0.1.0" + +[features] +default = ["derive", "serde"] +derive = ["linked-data-derive"] + +[dependencies] +rdf-types = "0.22.0" +xsd-types = "0.9.2" +static-iref = "3.0" +json-syntax = { version = "0.12.2", features = ["canonicalize"] } +educe = "0.4.22" +im = "15.1.0" +iref.workspace = true +thiserror.workspace = true +linked-data-derive = { workspace = true, optional = true } +serde = { version = "1.0", features = ["derive"], optional = true } + +[dev-dependencies] +json-syntax = { version = "0.12.2", features = ["serde"] } + +[[example]] +name = "derive" +required-features = ["derive"] + [workspace] members = [ - "linked-data", - "linked-data-derive" + "derive" ] resolver = "2" [workspace.dependencies] -linked-data = { version = "0.1", path = "linked-data" } -linked-data-derive = { version = "0.1", path = "linked-data-derive" } +linked-data-derive = { version = "0.1", path = "derive" } iref = "3.0" static-iref = "3.0" thiserror = "1.0.47" \ No newline at end of file diff --git a/README.md b/README.md index a766c66..f6f6e9f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Linked-Data serialization and deserialization primitives +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/spruceid/linked-data-rs/ci.yml?style=flat-square&logo=github)](https://github.com/spruceid/linked-data-rs/actions) +[![Crate informations](https://img.shields.io/crates/v/linked-data.svg?style=flat-square)](https://crates.io/crates/linked-data) +[![Crates.io MSRV](https://img.shields.io/crates/msrv/linked-data?style=flat-square)](https://crates.io/crates/linked-data) +[![License](https://img.shields.io/crates/l/linked-data.svg?style=flat-square)](https://github.com/spruceid/linked-data-rs#license) +[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square)](https://docs.rs/linked-data) + This library provides primitive traits to serialize and deserialize @@ -11,9 +17,8 @@ feature) that can automatically implement those primitives for you. ```rust use iref::IriBuf; use static_iref::iri; -use linked_data::LinkedData; -#[derive(LinkedData)] +#[derive(linked_data::Serialize, linked_data::Deserialize)] #[ld(prefix("ex" = "http://example.org/"))] struct Foo { #[ld(id)] @@ -32,7 +37,9 @@ let value = Foo { email: "john.smith@example.org".to_owned() }; -let quads = linked_data::to_quads(rdf_types::generator::Blank::new(), &value).expect("RDF serialization failed"); +let quads = linked_data::to_quads(rdf_types::generator::Blank::new(), &value) + .expect("RDF serialization failed"); + for quad in quads { use rdf_types::RdfDisplay; println!("{} .", quad.rdf_display()) @@ -46,3 +53,18 @@ This should print the following: ``` + +## License + +Licensed under either of + + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..52015f1 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,60 @@ +[changelog] +header = """ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +""" + +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - [{{ commit.id | truncate(length=7, end="") }}] {{ commit.message }}\ + {% endfor %} +{% endfor %}\n +""" +# Remove the leading and trailing whitespace. +trim = true + +[git] +# Ignore conventional commits. +conventional_commits = false +filter_unconventional = false + +# Process each line of a commit as an individual commit. +split_commits = true + +# Regex for parsing and grouping commits. +commit_parsers = [ + { message = "^[aA]dd( |ed)", group = "Added"}, + { message = "^[iI]mpl", group = "Added"}, + { message = "^[fF]ix( |ed)", group = "Fixed"}, + { message = "^[cC]hange( |ed)", group = "Changed"}, + { message = "^[mM]ove( |d)", group = "Changed"}, + { message = "^[rR]estructure( |d)", group = "Changed"}, + { message = "^[rR]efactor( |ed)", group = "Changed"}, + { message = "^[rR]emove( |d)", group = "Removed"}, + { message = "^[uU]pgrade( |d)", group = "Build"}, + { message = "^[bB]ump( |ed)", group = "Build"} +] + +# Protect breaking changes from being skipped due to matching a skipping commit_parser. +protect_breaking_commits = false + +# Filter out the commits that are not matched by commit parsers. +filter_commits = true + +# Glob pattern for matching git tags +tag_pattern = "[0-9\\.]*" + +# Sort the commits inside sections by oldest/newest order +sort_commits = "oldest" \ No newline at end of file diff --git a/linked-data-derive/Cargo.toml b/derive/Cargo.toml similarity index 100% rename from linked-data-derive/Cargo.toml rename to derive/Cargo.toml diff --git a/linked-data-derive/README.md b/derive/README.md similarity index 100% rename from linked-data-derive/README.md rename to derive/README.md diff --git a/linked-data-derive/src/generate.rs b/derive/src/generate.rs similarity index 98% rename from linked-data-derive/src/generate.rs rename to derive/src/generate.rs index d3b4fd5..01dc582 100644 --- a/linked-data-derive/src/generate.rs +++ b/derive/src/generate.rs @@ -126,7 +126,7 @@ impl ToTokens for VocabularyBounds { if self.iri_mut { tokens.extend(quote! { - + ::linked_data::rdf_types::IriVocabularyMut + + ::linked_data::rdf_types::vocabulary::IriVocabularyMut }) } } @@ -153,7 +153,7 @@ impl ToTokens for InterpretationBounds { if self.iri_mut { tokens.extend(quote! { - + ::linked_data::rdf_types::IriInterpretation + + ::linked_data::rdf_types::interpretation::IriInterpretation }) } diff --git a/linked-data-derive/src/generate/de.rs b/derive/src/generate/de.rs similarity index 97% rename from linked-data-derive/src/generate/de.rs rename to derive/src/generate/de.rs index 9a50591..23e1be2 100644 --- a/linked-data-derive/src/generate/de.rs +++ b/derive/src/generate/de.rs @@ -134,7 +134,7 @@ fn generate_field( interpretation_, dataset_, graph_, - ::objects(graph_, resource_, &predicate_), + ::linked_data::rdf_types::dataset::PatternMatchingDataset::quad_objects(dataset_, graph_, resource_, &predicate_), context_ )? } diff --git a/linked-data-derive/src/generate/de/enum.rs b/derive/src/generate/de/enum.rs similarity index 90% rename from linked-data-derive/src/generate/de/enum.rs rename to derive/src/generate/de/enum.rs index 06fc500..9ad3167 100644 --- a/linked-data-derive/src/generate/de/enum.rs +++ b/derive/src/generate/de/enum.rs @@ -48,7 +48,7 @@ pub fn generate( interpretation_, dataset_, graph_, - ::objects(graph_, resource_, &predicate), + ::linked_data::rdf_types::dataset::PatternMatchingDataset::quad_objects(dataset_, graph_, resource_, &predicate), context_ ); @@ -76,7 +76,7 @@ pub fn generate( quote! { match vocabulary_.get(unsafe { ::linked_data::iref::Iri::new_unchecked(#iri) }).and_then(|iri| interpretation_.iri_interpretation(&iri)) { Some(predicate) => { - let mut objects = ::objects(graph_, resource_, &predicate); + let mut objects = ::linked_data::rdf_types::dataset::PatternMatchingDataset::quad_objects(dataset_, graph_, resource_, &predicate); let result = match objects.next() { Some(resource_) => { @@ -125,7 +125,14 @@ pub fn generate( } } None => match variant_shape(&v.fields) { - VariantShape::Simple(_ty) => { + VariantShape::Simple(ty) => { + bounds.push( + syn::parse2( + quote!(#ty: ::linked_data::LinkedDataDeserializeSubject), + ) + .unwrap(), + ); + quote! { let result = ::linked_data::LinkedDataDeserializeSubject::deserialize_subject_in( vocabulary_, @@ -137,7 +144,7 @@ pub fn generate( ); match result { - Ok(value) => return Ok(value), + Ok(value) => return Ok(Self::#v_ident(value)), Err(e) => error = Some(e) } } @@ -182,12 +189,12 @@ pub fn generate( vocabulary_: &V_, interpretation_: &I_, dataset_: &D_, - graph_: &D_::Graph, + graph_: Option<&I_::Resource>, resource_: &I_::Resource, outer_context_: ::linked_data::Context ) -> Result where - D_: ::linked_data::grdf::Dataset + D_: ::linked_data::rdf_types::dataset::PatternMatchingDataset { let context_ = outer_context_.with_subject(resource_); let mut error = None; @@ -210,13 +217,13 @@ pub fn generate( vocabulary: &V_, interpretation: &I_, dataset: &D_, - graph: &D_::Graph, + graph: Option<&I_::Resource>, objects: impl IntoIterator, context: ::linked_data::Context ) -> Result where I_::Resource: 'de_, - D_: ::linked_data::grdf::Dataset + D_: ::linked_data::rdf_types::dataset::PatternMatchingDataset { let mut objects = objects.into_iter(); diff --git a/linked-data-derive/src/generate/de/struct.rs b/derive/src/generate/de/struct.rs similarity index 88% rename from linked-data-derive/src/generate/de/struct.rs rename to derive/src/generate/de/struct.rs index 2b08df9..d89e853 100644 --- a/linked-data-derive/src/generate/de/struct.rs +++ b/derive/src/generate/de/struct.rs @@ -31,12 +31,12 @@ pub fn generate( vocabulary_: &V_, interpretation_: &I_, dataset_: &D_, - graph_: &D_::Graph, + graph_: Option<&I_::Resource>, resource_: &I_::Resource, context_: ::linked_data::Context ) -> Result where - D_: ::linked_data::grdf::Dataset + D_: ::linked_data::rdf_types::dataset::PatternMatchingDataset { let context_ = context_.with_subject(resource_); #(#deserialize_fields)* @@ -49,13 +49,13 @@ pub fn generate( vocabulary: &V_, interpretation: &I_, dataset: &D_, - graph: &D_::Graph, + graph: Option<&I_::Resource>, objects: impl IntoIterator, context: ::linked_data::Context ) -> Result where I_::Resource: 'de_, - D_: ::linked_data::grdf::Dataset + D_: ::linked_data::rdf_types::dataset::PatternMatchingDataset { let mut objects = objects.into_iter(); diff --git a/linked-data-derive/src/generate/ser.rs b/derive/src/generate/ser.rs similarity index 100% rename from linked-data-derive/src/generate/ser.rs rename to derive/src/generate/ser.rs diff --git a/linked-data-derive/src/generate/ser/enum.rs b/derive/src/generate/ser/enum.rs similarity index 100% rename from linked-data-derive/src/generate/ser/enum.rs rename to derive/src/generate/ser/enum.rs diff --git a/linked-data-derive/src/generate/ser/struct.rs b/derive/src/generate/ser/struct.rs similarity index 100% rename from linked-data-derive/src/generate/ser/struct.rs rename to derive/src/generate/ser/struct.rs diff --git a/linked-data-derive/src/lib.rs b/derive/src/lib.rs similarity index 100% rename from linked-data-derive/src/lib.rs rename to derive/src/lib.rs diff --git a/linked-data-derive/src/utils.rs b/derive/src/utils.rs similarity index 100% rename from linked-data-derive/src/utils.rs rename to derive/src/utils.rs diff --git a/linked-data/examples/derive.rs b/examples/derive.rs similarity index 100% rename from linked-data/examples/derive.rs rename to examples/derive.rs diff --git a/linked-data/examples/derive_enum.rs b/examples/derive_enum.rs similarity index 100% rename from linked-data/examples/derive_enum.rs rename to examples/derive_enum.rs diff --git a/linked-data/examples/generics.rs b/examples/generics.rs similarity index 100% rename from linked-data/examples/generics.rs rename to examples/generics.rs diff --git a/linked-data/examples/graph.rs b/examples/graph.rs similarity index 100% rename from linked-data/examples/graph.rs rename to examples/graph.rs diff --git a/linked-data/Cargo.toml b/linked-data/Cargo.toml deleted file mode 100644 index e55c166..0000000 --- a/linked-data/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "linked-data" -version = "0.1.0" -edition = "2021" - -[features] -default = ["derive", "serde"] -derive = ["linked-data-derive"] - -[dependencies] -rdf-types = "0.18.1" -xsd-types = "0.9.1" -grdf = "0.22" -static-iref = "3.0" -json-syntax = { version = "0.12", features = ["canonicalize"] } -iref.workspace = true -linked-data-derive = { workspace = true, optional = true } -thiserror.workspace = true -educe = "0.4.22" -serde = { version = "1.0", features = ["derive"], optional = true } -im = "15.1.0" - -[dev-dependencies] -json-syntax = { version = "0.12", features = ["serde"] } - -[[example]] -name = "derive" -required-features = ["derive"] \ No newline at end of file diff --git a/linked-data/README.md b/linked-data/README.md deleted file mode 100644 index a766c66..0000000 --- a/linked-data/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Linked-Data serialization and deserialization primitives - - - -This library provides primitive traits to serialize and deserialize -Linked-Data types. It is shipped with derive macros (using the `derive` -feature) that can automatically implement those primitives for you. - -## Example - -```rust -use iref::IriBuf; -use static_iref::iri; -use linked_data::LinkedData; - -#[derive(LinkedData)] -#[ld(prefix("ex" = "http://example.org/"))] -struct Foo { - #[ld(id)] - id: IriBuf, - - #[ld("ex:name")] - name: String, - - #[ld("ex:email")] - email: String -} - -let value = Foo { - id: iri!("http://example.org/JohnSmith").to_owned(), - name: "John Smith".to_owned(), - email: "john.smith@example.org".to_owned() -}; - -let quads = linked_data::to_quads(rdf_types::generator::Blank::new(), &value).expect("RDF serialization failed"); -for quad in quads { - use rdf_types::RdfDisplay; - println!("{} .", quad.rdf_display()) -} -``` - -This should print the following: -```text - "John Smith" . - "john.smith@example.org" . -``` - - diff --git a/linked-data/src/impl.rs b/linked-data/src/impl.rs deleted file mode 100644 index ff3bb8e..0000000 --- a/linked-data/src/impl.rs +++ /dev/null @@ -1 +0,0 @@ -mod grdf; diff --git a/linked-data/src/impl/grdf.rs b/linked-data/src/impl/grdf.rs deleted file mode 100644 index 142e1c6..0000000 --- a/linked-data/src/impl/grdf.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod graph_view; -mod view; diff --git a/linked-data/src/impl/grdf/graph_view.rs b/linked-data/src/impl/grdf/graph_view.rs deleted file mode 100644 index 3af9039..0000000 --- a/linked-data/src/impl/grdf/graph_view.rs +++ /dev/null @@ -1,186 +0,0 @@ -use grdf::{Graph, GraphAccess, GraphView}; -use rdf_types::{Interpretation, Vocabulary}; -use std::hash::Hash; - -use crate::{ - LinkedDataPredicateObjects, LinkedDataResource, LinkedDataSubject, PredicateObjectsVisitor, - ResourceInterpretation, SubjectVisitor, -}; - -impl<'a, G: ?Sized + Graph, A: GraphAccess, I: Interpretation, V: Vocabulary> - LinkedDataSubject for GraphView<'a, G, A> -where - G::Subject: Eq + Hash, - G::Predicate: LinkedDataResource, - G::Object: LinkedDataResource, -{ - fn visit_subject(&self, mut serializer: S) -> Result - where - S: SubjectVisitor, - { - let mut visited = im::HashSet::new(); - visited.insert(self.subject); - - Subject::new(self.graph, self.subject, &self.access, &visited, true) - .visit(&mut serializer)?; - serializer.end() - } -} - -struct PredicateObjects<'d, 'v, G: ?Sized + Graph, A> { - graph: &'d G, - subject: &'d G::Subject, - predicate: &'d G::Predicate, - access: &'d A, - visited: &'v im::HashSet<&'d G::Subject>, -} - -impl<'d, 'v, G: ?Sized + Graph, A: GraphAccess, I: Interpretation, V: Vocabulary> - LinkedDataPredicateObjects for PredicateObjects<'d, 'v, G, A> -where - G::Subject: Eq + Hash, - G::Predicate: LinkedDataResource, - G::Object: LinkedDataResource, -{ - fn visit_objects(&self, mut visitor: S) -> Result - where - S: PredicateObjectsVisitor, - { - for object in self.graph.objects(self.subject, self.predicate) { - visitor.object(&Object { - graph: self.graph, - object, - access: self.access, - visited: self.visited, - })?; - } - - visitor.end() - } -} - -impl<'a, 'v, G: ?Sized + Graph, A, I: Interpretation, V: Vocabulary> LinkedDataResource - for Object<'a, 'v, G, A> -where - G::Object: LinkedDataResource, -{ - fn interpretation( - &self, - vocabulary: &mut V, - interpretation: &mut I, - ) -> ResourceInterpretation { - self.object.interpretation(vocabulary, interpretation) - } -} - -struct Object<'a, 'v, G: ?Sized + Graph, A> { - graph: &'a G, - object: &'a G::Object, - access: &'a A, - visited: &'v im::HashSet<&'a G::Subject>, -} - -impl<'a, 'v, G: ?Sized + Graph, A: GraphAccess, I: Interpretation, V: Vocabulary> - LinkedDataSubject for Object<'a, 'v, G, A> -where - G::Subject: Eq + Hash, - G::Predicate: LinkedDataResource, - G::Object: LinkedDataResource, -{ - fn visit_subject(&self, mut visitor: S) -> Result - where - S: SubjectVisitor, - { - if let Some(subject) = self.access.object_as_subject(self.graph, self.object) { - let mut visited = self.visited.clone(); - let visit_predicates = visited.insert(subject).is_none(); - - Subject::new(self.graph, subject, self.access, &visited, visit_predicates) - .visit(&mut visitor)?; - } - - visitor.end() - } -} - -struct Subject<'a, 'v, G: ?Sized + Graph, A> { - graph: &'a G, - subject: &'a G::Subject, - access: &'a A, - visited: &'v im::HashSet<&'a G::Subject>, - visit_predicates: bool, -} - -impl<'a, 'v, G: ?Sized + Graph, A> Subject<'a, 'v, G, A> -where - G::Subject: Eq + Hash, -{ - fn new( - graph: &'a G, - subject: &'a G::Subject, - access: &'a A, - visited: &'v im::HashSet<&'a G::Subject>, - visit_predicates: bool, - ) -> Self { - Self { - graph, - subject, - access, - visited, - visit_predicates, - } - } - - fn visit(&self, visitor: &mut S) -> Result<(), S::Error> - where - A: GraphAccess, - S: SubjectVisitor, - G::Predicate: LinkedDataResource, - G::Object: LinkedDataResource, - { - for (predicate, _) in self.graph.predicates(self.subject) { - visitor.predicate( - predicate, - &PredicateObjects { - graph: self.graph, - subject: self.subject, - predicate, - access: self.access, - visited: self.visited, - }, - )?; - } - - Ok(()) - } -} - -impl<'a, 'v, G: ?Sized + Graph, A: GraphAccess, I: Interpretation, V: Vocabulary> - LinkedDataSubject for Subject<'a, 'v, G, A> -where - G::Subject: Eq + Hash, - G::Predicate: LinkedDataResource, - G::Object: LinkedDataResource, -{ - fn visit_subject(&self, mut visitor: S) -> Result - where - S: SubjectVisitor, - { - if self.visit_predicates { - for (predicate, _) in self.graph.predicates(self.subject) { - visitor.predicate( - predicate, - &PredicateObjects { - graph: self.graph, - subject: self.subject, - predicate, - access: self.access, - visited: self.visited, - }, - )?; - } - } - - visitor.end() - } -} diff --git a/linked-data/src/impl/grdf/view.rs b/linked-data/src/impl/grdf/view.rs deleted file mode 100644 index bdf4179..0000000 --- a/linked-data/src/impl/grdf/view.rs +++ /dev/null @@ -1,317 +0,0 @@ -use std::hash::Hash; - -use crate::{ - GraphVisitor, LinkedDataGraph, LinkedDataPredicateObjects, LinkedDataResource, - LinkedDataSubject, PredicateObjectsVisitor, ResourceInterpretation, SubjectVisitor, -}; -use grdf::{Dataset, DatasetAccess, Graph, View}; -use rdf_types::{Interpretation, Vocabulary}; - -impl<'a, D: ?Sized + Dataset, A: DatasetAccess, I: Interpretation, V: Vocabulary> - LinkedDataSubject for View<'a, D, A> -where - D::Subject: Eq + Hash + LinkedDataResource, - D::Predicate: LinkedDataResource, - D::Object: LinkedDataResource, - D::GraphLabel: Eq + Hash + LinkedDataResource, -{ - fn visit_subject(&self, mut serializer: S) -> Result - where - S: SubjectVisitor, - { - let mut visited_subjects = im::HashSet::new(); - visited_subjects.insert(self.subject); - - let mut visited_graphs = im::HashSet::new(); - if let Some(graph_label) = self.graph_label { - visited_graphs.insert(graph_label); - } - - if let Some(graph) = self.graph { - Subject::new( - self.dataset, - graph, - self.subject, - &self.access, - &visited_subjects, - &visited_graphs, - true, - ) - .visit(&mut serializer)?; - } - - serializer.end() - } -} - -struct PredicateObjects<'d, 'v, D: ?Sized + Dataset, A> { - dataset: &'d D, - graph: &'d D::Graph, - subject: &'d D::Subject, - predicate: &'d D::Predicate, - access: &'d A, - visited_subjects: &'v im::HashSet<&'d D::Subject>, - visited_graphs: &'v im::HashSet<&'d D::GraphLabel>, -} - -impl<'d, 'v, D: ?Sized + Dataset, A: DatasetAccess, I: Interpretation, V: Vocabulary> - LinkedDataPredicateObjects for PredicateObjects<'d, 'v, D, A> -where - D::Subject: Eq + Hash + LinkedDataResource, - D::Predicate: LinkedDataResource, - D::Object: LinkedDataResource, - D::GraphLabel: Eq + Hash + LinkedDataResource, -{ - fn visit_objects(&self, mut visitor: S) -> Result - where - S: PredicateObjectsVisitor, - { - for object in self.graph.objects(self.subject, self.predicate) { - visitor.object(&Object { - dataset: self.dataset, - graph: self.graph, - object, - access: self.access, - visited_subjects: self.visited_subjects, - visited_graphs: self.visited_graphs, - })?; - } - - visitor.end() - } -} - -impl<'a, 'v, D: ?Sized + Dataset, A, I: Interpretation, V: Vocabulary> LinkedDataResource - for Object<'a, 'v, D, A> -where - D::Object: LinkedDataResource, -{ - fn interpretation( - &self, - vocabulary: &mut V, - interpretation: &mut I, - ) -> ResourceInterpretation { - self.object.interpretation(vocabulary, interpretation) - } -} - -struct Object<'a, 'v, D: ?Sized + Dataset, A> { - dataset: &'a D, - graph: &'a D::Graph, - object: &'a D::Object, - access: &'a A, - visited_subjects: &'v im::HashSet<&'a D::Subject>, - visited_graphs: &'v im::HashSet<&'a D::GraphLabel>, -} - -impl<'a, 'v, D: ?Sized + Dataset, A: DatasetAccess, I: Interpretation, V: Vocabulary> - LinkedDataSubject for Object<'a, 'v, D, A> -where - D::Subject: Eq + Hash + LinkedDataResource, - D::Predicate: LinkedDataResource, - D::Object: LinkedDataResource, - D::GraphLabel: Eq + Hash + LinkedDataResource, -{ - fn visit_subject(&self, mut visitor: S) -> Result - where - S: SubjectVisitor, - { - if let Some(subject) = self.access.object_as_subject(self.graph, self.object) { - let mut visited_subjects = self.visited_subjects.clone(); - let visit_predicates = visited_subjects.insert(subject).is_none(); - - Subject::new( - self.dataset, - self.graph, - subject, - self.access, - &visited_subjects, - self.visited_graphs, - visit_predicates, - ) - .visit(&mut visitor)?; - } - - visitor.end() - } -} - -struct Subject<'a, 'v, D: ?Sized + Dataset, A> { - dataset: &'a D, - graph: &'a D::Graph, - subject: &'a D::Subject, - access: &'a A, - visited_subjects: &'v im::HashSet<&'a D::Subject>, - visited_graphs: &'v im::HashSet<&'a D::GraphLabel>, - visit_predicates: bool, -} - -impl<'a, 'v, D: ?Sized + Dataset, A> Subject<'a, 'v, D, A> -where - D::Subject: Eq + Hash, - D::GraphLabel: Eq + Hash, -{ - fn new( - dataset: &'a D, - graph: &'a D::Graph, - subject: &'a D::Subject, - access: &'a A, - visited_subjects: &'v im::HashSet<&'a D::Subject>, - visited_graphs: &'v im::HashSet<&'a D::GraphLabel>, - visit_predicates: bool, - ) -> Self { - Self { - dataset, - graph, - subject, - access, - visited_subjects, - visited_graphs, - visit_predicates, - } - } - - fn visit(&self, visitor: &mut S) -> Result<(), S::Error> - where - A: DatasetAccess, - S: SubjectVisitor, - D::Subject: LinkedDataResource, - D::Predicate: LinkedDataResource, - D::Object: LinkedDataResource, - D::GraphLabel: LinkedDataResource, - { - if self.visit_predicates { - for (predicate, _) in self.graph.predicates(self.subject) { - visitor.predicate( - predicate, - &PredicateObjects { - dataset: self.dataset, - graph: self.graph, - subject: self.subject, - predicate, - access: self.access, - visited_subjects: self.visited_subjects, - visited_graphs: self.visited_graphs, - }, - )?; - } - - if let Some(label) = self.access.subject_as_graph(self.dataset, self.subject) { - let mut visited_graphs = self.visited_graphs.clone(); - if visited_graphs.insert(label).is_none() { - if let Some(graph) = self.dataset.graph(Some(label)) { - visitor.graph(&GraphView { - dataset: self.dataset, - label, - graph, - access: self.access, - visited_graphs: &visited_graphs, - })?; - } - } - } - } - - Ok(()) - } -} - -impl<'a, 'v, D: ?Sized + Dataset, A, I: Interpretation, V: Vocabulary> LinkedDataResource - for Subject<'a, 'v, D, A> -where - D::Subject: LinkedDataResource, -{ - fn interpretation( - &self, - vocabulary: &mut V, - interpretation: &mut I, - ) -> ResourceInterpretation { - self.subject.interpretation(vocabulary, interpretation) - } -} - -impl<'a, 'v, D: ?Sized + Dataset, A: DatasetAccess, I: Interpretation, V: Vocabulary> - LinkedDataSubject for Subject<'a, 'v, D, A> -where - D::Subject: Eq + Hash + LinkedDataResource, - D::Predicate: LinkedDataResource, - D::Object: LinkedDataResource, - D::GraphLabel: Eq + Hash + LinkedDataResource, -{ - fn visit_subject(&self, mut visitor: S) -> Result - where - S: SubjectVisitor, - { - for (predicate, _) in self.graph.predicates(self.subject) { - visitor.predicate( - predicate, - &PredicateObjects { - dataset: self.dataset, - graph: self.graph, - subject: self.subject, - predicate, - access: self.access, - visited_subjects: self.visited_subjects, - visited_graphs: self.visited_graphs, - }, - )?; - } - - visitor.end() - } -} - -struct GraphView<'a, 'v, D: ?Sized + Dataset, A> { - dataset: &'a D, - label: &'a D::GraphLabel, - graph: &'a D::Graph, - access: &'a A, - visited_graphs: &'v im::HashSet<&'a D::GraphLabel>, -} - -impl<'a, 'v, D: ?Sized + Dataset, A, I: Interpretation, V: Vocabulary> LinkedDataResource - for GraphView<'a, 'v, D, A> -where - D::GraphLabel: LinkedDataResource, -{ - fn interpretation( - &self, - vocabulary: &mut V, - interpretation: &mut I, - ) -> ResourceInterpretation { - self.label.interpretation(vocabulary, interpretation) - } -} - -impl<'a, 'v, D: ?Sized + Dataset, A: DatasetAccess, I: Interpretation, V: Vocabulary> - LinkedDataGraph for GraphView<'a, 'v, D, A> -where - D::Subject: Eq + Hash + LinkedDataResource, - D::Predicate: LinkedDataResource, - D::Object: LinkedDataResource, - D::GraphLabel: Eq + Hash + LinkedDataResource, -{ - fn visit_graph(&self, mut visitor: S) -> Result - where - S: GraphVisitor, - { - let mut visited_subjects = im::HashSet::new(); - for (subject, _) in self.graph.subjects() { - visited_subjects.insert(subject); - } - - for (subject, _) in self.graph.subjects() { - visitor.subject(&Subject::new( - self.dataset, - self.graph, - subject, - self.access, - &visited_subjects, - self.visited_graphs, - true, - ))?; - } - - visitor.end() - } -} diff --git a/linked-data/src/anonymous.rs b/src/anonymous.rs similarity index 96% rename from linked-data/src/anonymous.rs rename to src/anonymous.rs index ad26d8e..5b037bd 100644 --- a/linked-data/src/anonymous.rs +++ b/src/anonymous.rs @@ -1,5 +1,5 @@ use iref::Iri; -use rdf_types::{Interpretation, IriVocabularyMut, Vocabulary}; +use rdf_types::{vocabulary::IriVocabularyMut, Interpretation, Vocabulary}; use crate::{ GraphVisitor, LinkedData, LinkedDataGraph, LinkedDataPredicateObjects, LinkedDataResource, diff --git a/linked-data/src/datatypes/de.rs b/src/datatypes/de.rs similarity index 72% rename from linked-data/src/datatypes/de.rs rename to src/datatypes/de.rs index dffec2b..449e19f 100644 --- a/linked-data/src/datatypes/de.rs +++ b/src/datatypes/de.rs @@ -1,6 +1,7 @@ use rdf_types::{ - Interpretation, IriVocabulary, LanguageTagVocabulary, LiteralVocabulary, - ReverseIriInterpretation, ReverseLiteralInterpretation, Vocabulary, RDF_LANG_STRING, + interpretation::{ReverseIriInterpretation, ReverseLiteralInterpretation}, + vocabulary::LiteralVocabulary, + Interpretation, Vocabulary, RDF_LANG_STRING, }; use crate::{ @@ -13,32 +14,28 @@ macro_rules! deserialize_datatype { $( impl LinkedDataDeserializeSubject for $ty where - V: LiteralVocabulary::Iri, - ::LanguageTag, - >>, - V::Value: AsRef, + V: LiteralVocabulary, I: ReverseIriInterpretation + ReverseLiteralInterpretation { fn deserialize_subject_in( vocabulary: &V, interpretation: &I, _dataset: &D, - _graph: &D::Graph, + _graph: Option<&I::Resource>, resource: &I::Resource, context: Context ) -> Result where - D: grdf::Dataset + D: rdf_types::dataset::PatternMatchingDataset { let mut literal_ty = None; for l in interpretation.literals_of(resource) { let l = vocabulary.literal(l).unwrap(); - match l.type_() { - rdf_types::literal::Type::Any(ty_iri) => { + match l.type_ { + rdf_types::LiteralTypeRef::Any(ty_iri) => { let ty_iri = vocabulary.iri(ty_iri).unwrap(); if ty_iri == xsd_types::$iri { - return match l.value().as_ref().parse() { + return match l.value.parse() { Ok(value) => Ok(value), Err(_) => Err(FromLinkedDataError::InvalidLiteral( context.into_iris( @@ -51,7 +48,7 @@ macro_rules! deserialize_datatype { literal_ty = Some(ty_iri) } - rdf_types::literal::Type::LangString(_) => { + rdf_types::LiteralTypeRef::LangString(_) => { literal_ty = Some(RDF_LANG_STRING) } } @@ -76,24 +73,20 @@ macro_rules! deserialize_datatype { impl LinkedDataDeserializePredicateObjects for $ty where - V: LiteralVocabulary::Iri, - ::LanguageTag, - >>, - V::Value: AsRef, + V: LiteralVocabulary, I: ReverseIriInterpretation + ReverseLiteralInterpretation { fn deserialize_objects_in<'a, D>( vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, objects: impl IntoIterator::Resource>, context: Context ) -> Result where ::Resource: 'a, - D: grdf::Dataset::Resource, Predicate = ::Resource, Object = ::Resource, GraphLabel = ::Resource> + D: rdf_types::dataset::PatternMatchingDataset { let mut error = None; diff --git a/linked-data/src/datatypes.rs b/src/datatypes/mod.rs similarity index 100% rename from linked-data/src/datatypes.rs rename to src/datatypes/mod.rs diff --git a/linked-data/src/datatypes/ser.rs b/src/datatypes/ser.rs similarity index 81% rename from linked-data/src/datatypes/ser.rs rename to src/datatypes/ser.rs index 2ad6d1c..94df846 100644 --- a/linked-data/src/datatypes/ser.rs +++ b/src/datatypes/ser.rs @@ -1,4 +1,7 @@ -use rdf_types::{Id, Interpretation, IriVocabularyMut, LiteralVocabularyMut, Term, Vocabulary}; +use rdf_types::{ + vocabulary::{IriVocabularyMut, LiteralVocabularyMut}, + Id, Interpretation, Term, Vocabulary, +}; use crate::{ CowRdfTerm, LinkedDataPredicateObjects, LinkedDataResource, LinkedDataSubject, @@ -8,10 +11,7 @@ use crate::{ macro_rules! datatype { ($($ty:ty : $variant:ident),*) => { $( - impl LinkedDataResource for $ty - where - V::Value: From - { + impl LinkedDataResource for $ty { fn interpretation( &self, _vocabulary: &mut V, @@ -23,10 +23,7 @@ macro_rules! datatype { } } - impl LinkedDataSubject for $ty - where - V::Value: From - { + impl LinkedDataSubject for $ty { fn visit_subject(&self, visitor: S) -> Result where S: crate::SubjectVisitor @@ -35,10 +32,7 @@ macro_rules! datatype { } } - impl LinkedDataPredicateObjects for $ty - where - V::Value: From - { + impl LinkedDataPredicateObjects for $ty { fn visit_objects(&self, mut visitor: S) -> Result where S: PredicateObjectsVisitor, @@ -54,10 +48,7 @@ macro_rules! datatype { macro_rules! unsized_datatype { ($($ty:ty : $variant:ident),*) => { $( - impl LinkedDataResource for $ty - where - V::Value: From - { + impl LinkedDataResource for $ty { fn interpretation( &self, _vocabulary: &mut V, @@ -69,10 +60,7 @@ macro_rules! unsized_datatype { } } - impl LinkedDataSubject for $ty - where - V::Value: From - { + impl LinkedDataSubject for $ty { fn visit_subject(&self, visitor: S) -> Result where S: crate::SubjectVisitor @@ -81,10 +69,7 @@ macro_rules! unsized_datatype { } } - impl LinkedDataPredicateObjects for $ty - where - V::Value: From - { + impl LinkedDataPredicateObjects for $ty { fn visit_objects(&self, mut visitor: S) -> Result where S: PredicateObjectsVisitor, @@ -116,8 +101,6 @@ unsized_datatype! { impl LinkedDataResource for xsd_types::AnyUriBuf -where - V::Value: From, { fn interpretation( &self, @@ -142,8 +125,6 @@ where impl LinkedDataSubject for xsd_types::AnyUriBuf -where - V::Value: From, { fn visit_subject(&self, visitor: S) -> Result where @@ -155,8 +136,6 @@ where impl LinkedDataPredicateObjects for xsd_types::AnyUriBuf -where - V::Value: From, { fn visit_objects(&self, mut visitor: S) -> Result where diff --git a/linked-data/src/graph.rs b/src/graph.rs similarity index 100% rename from linked-data/src/graph.rs rename to src/graph.rs diff --git a/src/impl/mod.rs b/src/impl/mod.rs new file mode 100644 index 0000000..8346584 --- /dev/null +++ b/src/impl/mod.rs @@ -0,0 +1 @@ +mod rdf_types; diff --git a/src/impl/rdf_types/dataset_graph_view.rs b/src/impl/rdf_types/dataset_graph_view.rs new file mode 100644 index 0000000..068cfc7 --- /dev/null +++ b/src/impl/rdf_types/dataset_graph_view.rs @@ -0,0 +1,193 @@ +use rdf_types::{ + dataset::{DatasetGraphView, PatternMatchingDataset, PredicateTraversableDataset}, + Dataset, Interpretation, Vocabulary, +}; +use std::hash::Hash; + +use crate::{ + LinkedDataPredicateObjects, LinkedDataResource, LinkedDataSubject, PredicateObjectsVisitor, + ResourceInterpretation, SubjectVisitor, +}; + +impl<'a, I: Interpretation, V: Vocabulary, D> LinkedDataSubject for DatasetGraphView<'a, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: PredicateTraversableDataset + PatternMatchingDataset, +{ + fn visit_subject(&self, mut serializer: S) -> Result + where + S: SubjectVisitor, + { + let mut visited = im::HashSet::new(); + visited.insert(self.resource); + + Subject::new(self.dataset, self.graph, self.resource, &visited, true) + .visit(&mut serializer)?; + serializer.end() + } +} + +struct PredicateObjects<'d, 'v, D: Dataset> { + dataset: &'d D, + graph: Option<&'d D::Resource>, + subject: &'d D::Resource, + predicate: &'d D::Resource, + visited: &'v im::HashSet<&'d D::Resource>, +} + +impl<'d, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataPredicateObjects + for PredicateObjects<'d, 'v, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: PredicateTraversableDataset + PatternMatchingDataset, +{ + fn visit_objects(&self, mut visitor: S) -> Result + where + S: PredicateObjectsVisitor, + { + for object in self + .dataset + .quad_objects(self.graph, self.subject, self.predicate) + { + visitor.object(&Object { + dataset: self.dataset, + graph: self.graph, + object, + visited: self.visited, + })?; + } + + visitor.end() + } +} + +impl<'a, 'v, I: Interpretation, V: Vocabulary, D: Dataset> + LinkedDataResource for Object<'a, 'v, D> +where + I::Resource: LinkedDataResource, +{ + fn interpretation( + &self, + vocabulary: &mut V, + interpretation: &mut I, + ) -> ResourceInterpretation { + self.object.interpretation(vocabulary, interpretation) + } +} + +struct Object<'d, 'v, D: Dataset> { + dataset: &'d D, + graph: Option<&'d D::Resource>, + object: &'d D::Resource, + visited: &'v im::HashSet<&'d D::Resource>, +} + +impl<'d, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataSubject for Object<'d, 'v, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: PredicateTraversableDataset + PatternMatchingDataset, +{ + fn visit_subject(&self, mut visitor: S) -> Result + where + S: SubjectVisitor, + { + let subject = self.object; + let mut visited = self.visited.clone(); + let visit_predicates = visited.insert(subject).is_none(); + + Subject::new( + self.dataset, + self.graph, + subject, + &visited, + visit_predicates, + ) + .visit(&mut visitor)?; + + visitor.end() + } +} + +struct Subject<'d, 'v, D: Dataset> { + dataset: &'d D, + graph: Option<&'d D::Resource>, + subject: &'d D::Resource, + visited: &'v im::HashSet<&'d D::Resource>, + visit_predicates: bool, +} + +impl<'d, 'v, D: PredicateTraversableDataset + PatternMatchingDataset> Subject<'d, 'v, D> { + fn new( + dataset: &'d D, + graph: Option<&'d D::Resource>, + subject: &'d D::Resource, + visited: &'v im::HashSet<&'d D::Resource>, + visit_predicates: bool, + ) -> Self { + Self { + dataset, + graph, + subject, + visited, + visit_predicates, + } + } + + fn visit, V: Vocabulary, S>( + &self, + visitor: &mut S, + ) -> Result<(), S::Error> + where + S: SubjectVisitor, + I::Resource: Eq + Hash + LinkedDataResource, + { + for (predicate, _) in self + .dataset + .quad_predicates_objects(self.graph, self.subject) + { + visitor.predicate( + predicate, + &PredicateObjects { + dataset: self.dataset, + graph: self.graph, + subject: self.subject, + predicate, + visited: self.visited, + }, + )?; + } + + Ok(()) + } +} + +impl<'d, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataSubject for Subject<'d, 'v, D> +where + D::Resource: Eq + Hash + LinkedDataResource, + D: PredicateTraversableDataset + PatternMatchingDataset, +{ + fn visit_subject(&self, mut visitor: S) -> Result + where + S: SubjectVisitor, + { + if self.visit_predicates { + for (predicate, _) in self + .dataset + .quad_predicates_objects(self.graph, self.subject) + { + visitor.predicate( + predicate, + &PredicateObjects { + dataset: self.dataset, + graph: self.graph, + subject: self.subject, + predicate, + visited: self.visited, + }, + )?; + } + } + + visitor.end() + } +} diff --git a/src/impl/rdf_types/dataset_view.rs b/src/impl/rdf_types/dataset_view.rs new file mode 100644 index 0000000..f91dfe8 --- /dev/null +++ b/src/impl/rdf_types/dataset_view.rs @@ -0,0 +1,337 @@ +use std::hash::Hash; + +use crate::{ + GraphVisitor, LinkedDataGraph, LinkedDataPredicateObjects, LinkedDataResource, + LinkedDataSubject, PredicateObjectsVisitor, ResourceInterpretation, SubjectVisitor, +}; +use rdf_types::{ + dataset::{ + DatasetView, PatternMatchingDataset, PredicateTraversableDataset, SubjectTraversableDataset, + }, + Dataset, Interpretation, Quad, Vocabulary, +}; + +impl<'a, I: Interpretation, V: Vocabulary, D> LinkedDataGraph for DatasetView<'a, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: SubjectTraversableDataset + + PredicateTraversableDataset + + PatternMatchingDataset, +{ + fn visit_graph(&self, mut visitor: S) -> Result + where + S: GraphVisitor, + { + let mut visited_subjects = im::HashSet::new(); + let mut visited_graphs = im::HashSet::new(); + if let Some(g) = self.graph { + visited_graphs.insert(g); + } + + let mut graph_subjects = Vec::new(); + + for subject in self.dataset.subjects() { + if self.graph.is_none() + || self + .dataset + .quad_pattern_matching(Quad(Some(subject), None, None, Some(self.graph)).into()) + .next() + .is_some() + { + visited_subjects.insert(subject); + graph_subjects.push(subject); + } + } + + for subject in graph_subjects { + visitor.subject(&Subject::new( + self.dataset, + self.graph, + subject, + &visited_subjects, + &visited_graphs, + true, + ))?; + } + + visitor.end() + } +} + +struct PredicateObjects<'d, 'v, D: Dataset> { + dataset: &'d D, + graph: Option<&'d D::Resource>, + subject: &'d D::Resource, + predicate: &'d D::Resource, + visited_subjects: &'v im::HashSet<&'d D::Resource>, + visited_graphs: &'v im::HashSet<&'d D::Resource>, +} + +impl<'d, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataPredicateObjects + for PredicateObjects<'d, 'v, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: SubjectTraversableDataset + + PredicateTraversableDataset + + PatternMatchingDataset, +{ + fn visit_objects(&self, mut visitor: S) -> Result + where + S: PredicateObjectsVisitor, + { + for object in self + .dataset + .quad_objects(self.graph, self.subject, self.predicate) + { + visitor.object(&Object { + dataset: self.dataset, + graph: self.graph, + object, + visited_subjects: self.visited_subjects, + visited_graphs: self.visited_graphs, + })?; + } + + visitor.end() + } +} + +impl<'a, 'v, D, I: Interpretation, V: Vocabulary> LinkedDataResource for Object<'a, 'v, D> +where + I::Resource: LinkedDataResource, + D: Dataset, +{ + fn interpretation( + &self, + vocabulary: &mut V, + interpretation: &mut I, + ) -> ResourceInterpretation { + self.object.interpretation(vocabulary, interpretation) + } +} + +struct Object<'a, 'v, D: Dataset> { + dataset: &'a D, + graph: Option<&'a D::Resource>, + object: &'a D::Resource, + visited_subjects: &'v im::HashSet<&'a D::Resource>, + visited_graphs: &'v im::HashSet<&'a D::Resource>, +} + +impl<'a, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataSubject for Object<'a, 'v, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: SubjectTraversableDataset + + PredicateTraversableDataset + + PatternMatchingDataset, +{ + fn visit_subject(&self, mut visitor: S) -> Result + where + S: SubjectVisitor, + { + let subject = self.object; + + let mut visited_subjects = self.visited_subjects.clone(); + let visit_predicates = visited_subjects.insert(subject).is_none(); + + Subject::new( + self.dataset, + self.graph, + subject, + &visited_subjects, + self.visited_graphs, + visit_predicates, + ) + .visit(&mut visitor)?; + + visitor.end() + } +} + +struct Subject<'a, 'v, D: Dataset> { + dataset: &'a D, + graph: Option<&'a D::Resource>, + subject: &'a D::Resource, + visited_subjects: &'v im::HashSet<&'a D::Resource>, + visited_graphs: &'v im::HashSet<&'a D::Resource>, + visit_predicates: bool, +} + +impl< + 'a, + 'v, + D: SubjectTraversableDataset + PredicateTraversableDataset + PatternMatchingDataset, + > Subject<'a, 'v, D> +where + D::Resource: Eq + Hash, +{ + fn new( + dataset: &'a D, + graph: Option<&'a D::Resource>, + subject: &'a D::Resource, + visited_subjects: &'v im::HashSet<&'a D::Resource>, + visited_graphs: &'v im::HashSet<&'a D::Resource>, + visit_predicates: bool, + ) -> Self { + Self { + dataset, + graph, + subject, + visited_subjects, + visited_graphs, + visit_predicates, + } + } + + fn visit, V: Vocabulary, S>( + &self, + visitor: &mut S, + ) -> Result<(), S::Error> + where + S: SubjectVisitor, + D::Resource: LinkedDataResource, + { + if self.visit_predicates { + for (predicate, _) in self + .dataset + .quad_predicates_objects(self.graph, self.subject) + { + visitor.predicate( + predicate, + &PredicateObjects { + dataset: self.dataset, + graph: self.graph, + subject: self.subject, + predicate, + visited_subjects: self.visited_subjects, + visited_graphs: self.visited_graphs, + }, + )?; + } + + if self.dataset.contains_named_graph(self.subject) { + let mut visited_graphs = self.visited_graphs.clone(); + if visited_graphs.insert(self.subject).is_none() { + visitor.graph(&NamedGraphView { + dataset: self.dataset, + graph: self.subject, + visited_graphs: &visited_graphs, + })?; + } + } + } + + Ok(()) + } +} + +impl<'a, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataResource for Subject<'a, 'v, D> +where + I::Resource: LinkedDataResource, + D: Dataset, +{ + fn interpretation( + &self, + vocabulary: &mut V, + interpretation: &mut I, + ) -> ResourceInterpretation { + self.subject.interpretation(vocabulary, interpretation) + } +} + +impl<'a, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataSubject for Subject<'a, 'v, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: SubjectTraversableDataset + + PredicateTraversableDataset + + PatternMatchingDataset, +{ + fn visit_subject(&self, mut visitor: S) -> Result + where + S: SubjectVisitor, + { + for (predicate, _) in self + .dataset + .quad_predicates_objects(self.graph, self.subject) + { + visitor.predicate( + predicate, + &PredicateObjects { + dataset: self.dataset, + graph: self.graph, + subject: self.subject, + predicate, + visited_subjects: self.visited_subjects, + visited_graphs: self.visited_graphs, + }, + )?; + } + + visitor.end() + } +} + +struct NamedGraphView<'a, 'v, D: Dataset> { + dataset: &'a D, + graph: &'a D::Resource, + visited_graphs: &'v im::HashSet<&'a D::Resource>, +} + +impl<'a, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataResource + for NamedGraphView<'a, 'v, D> +where + I::Resource: LinkedDataResource, + D: Dataset, +{ + fn interpretation( + &self, + vocabulary: &mut V, + interpretation: &mut I, + ) -> ResourceInterpretation { + self.graph.interpretation(vocabulary, interpretation) + } +} + +impl<'a, 'v, I: Interpretation, V: Vocabulary, D> LinkedDataGraph + for NamedGraphView<'a, 'v, D> +where + I::Resource: Eq + Hash + LinkedDataResource, + D: SubjectTraversableDataset + + PredicateTraversableDataset + + PatternMatchingDataset, +{ + fn visit_graph(&self, mut visitor: S) -> Result + where + S: GraphVisitor, + { + let mut visited_subjects = im::HashSet::new(); + let mut graph_subjects = Vec::new(); + + for subject in self.dataset.subjects() { + if self + .dataset + .quad_pattern_matching( + Quad(Some(subject), None, None, Some(Some(self.graph))).into(), + ) + .next() + .is_some() + { + visited_subjects.insert(subject); + graph_subjects.push(subject); + } + } + + for subject in graph_subjects { + visitor.subject(&Subject::new( + self.dataset, + Some(self.graph), + subject, + &visited_subjects, + self.visited_graphs, + true, + ))?; + } + + visitor.end() + } +} diff --git a/src/impl/rdf_types/mod.rs b/src/impl/rdf_types/mod.rs new file mode 100644 index 0000000..e56adf5 --- /dev/null +++ b/src/impl/rdf_types/mod.rs @@ -0,0 +1,2 @@ +mod dataset_graph_view; +mod dataset_view; diff --git a/linked-data/src/lib.rs b/src/lib.rs similarity index 95% rename from linked-data/src/lib.rs rename to src/lib.rs index 07044a3..5cb4f49 100644 --- a/linked-data/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,9 @@ //! email: "john.smith@example.org".to_owned() //! }; //! -//! let quads = linked_data::to_quads(rdf_types::generator::Blank::new(), &value).expect("RDF serialization failed"); +//! let quads = linked_data::to_quads(rdf_types::generator::Blank::new(), &value) +//! .expect("RDF serialization failed"); +//! //! for quad in quads { //! use rdf_types::RdfDisplay; //! println!("{} .", quad.rdf_display()) @@ -43,7 +45,12 @@ use educe::Educe; use iref::{Iri, IriBuf}; #[cfg(feature = "derive")] pub use linked_data_derive::{Deserialize, Serialize}; -use rdf_types::{Interpretation, IriVocabulary, ReverseIriInterpretation, Vocabulary}; +use rdf_types::{ + dataset::{PatternMatchingDataset, TraversableDataset}, + interpretation::ReverseIriInterpretation, + vocabulary::IriVocabulary, + Interpretation, Vocabulary, +}; #[doc(hidden)] pub use iref; @@ -57,9 +64,6 @@ pub use xsd_types; #[doc(hidden)] pub use json_syntax; -#[doc(hidden)] -pub use grdf; - mod anonymous; mod datatypes; mod graph; @@ -353,24 +357,14 @@ pub trait LinkedDataDeserialize: Siz fn deserialize_dataset_in( vocabulary: &V, interpretation: &I, - dataset: &impl grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + dataset: &(impl TraversableDataset + PatternMatchingDataset), context: Context, ) -> Result; fn deserialize_dataset( vocabulary: &V, interpretation: &I, - dataset: &impl grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + dataset: &(impl TraversableDataset + PatternMatchingDataset), ) -> Result { Self::deserialize_dataset_in(vocabulary, interpretation, dataset, Context::default()) } diff --git a/linked-data/src/macros.rs b/src/macros.rs similarity index 76% rename from linked-data/src/macros.rs rename to src/macros.rs index 449035f..a411679 100644 --- a/linked-data/src/macros.rs +++ b/src/macros.rs @@ -30,26 +30,20 @@ macro_rules! json_literal { impl $crate::LinkedDataDeserializePredicateObjects for $ty where - V: $crate::rdf_types::Vocabulary::Iri, ::LanguageTag>>, - V::Value: AsRef, - I: $crate::rdf_types::ReverseIriInterpretation + $crate::rdf_types::ReverseLiteralInterpretation + V: $crate::rdf_types::Vocabulary, + I: $crate::rdf_types::interpretation::ReverseIriInterpretation + $crate::rdf_types::interpretation::ReverseLiteralInterpretation { fn deserialize_objects_in<'a, D>( vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, objects: impl IntoIterator, context: $crate::Context ) -> Result where I::Resource: 'a, - D: $crate::grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - > + D: $crate::rdf_types::dataset::PatternMatchingDataset { let mut objects = objects.into_iter(); match objects.next() { @@ -82,37 +76,31 @@ macro_rules! json_literal { impl $crate::LinkedDataDeserializeSubject for $ty where - V: $crate::rdf_types::Vocabulary::Iri, ::LanguageTag>>, - V::Value: AsRef, - I: $crate::rdf_types::ReverseIriInterpretation + $crate::rdf_types::ReverseLiteralInterpretation + V: $crate::rdf_types::Vocabulary, + I: $crate::rdf_types::interpretation::ReverseIriInterpretation + $crate::rdf_types::interpretation::ReverseLiteralInterpretation { fn deserialize_subject_in( vocabulary: &V, interpretation: &I, _dataset: &D, - _graph: &D::Graph, + _graph: Option<&I::Resource>, resource: &I::Resource, context: $crate::Context ) -> Result where - D: $crate::grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - > + D: $crate::rdf_types::dataset::PatternMatchingDataset { - use $crate::rdf_types::literal; + use $crate::rdf_types::LiteralTypeRef; let mut literal_ty = None; for l in interpretation.literals_of(resource) { let literal = vocabulary.literal(l).unwrap(); - match literal.type_() { - literal::Type::Any(ty) => { + match literal.type_ { + LiteralTypeRef::Any(ty) => { let ty_iri = vocabulary.iri(ty).unwrap(); if ty_iri == $crate::rdf_types::RDF_JSON { use $crate::json_syntax::Parse; - let (json, _) = $crate::json_syntax::Value::parse_str(literal.value().as_ref()) + let (json, _) = $crate::json_syntax::Value::parse_str(literal.value) .map_err(|_| $crate::FromLinkedDataError::InvalidLiteral( context.into_iris(vocabulary, interpretation) ))?; @@ -124,7 +112,7 @@ macro_rules! json_literal { literal_ty = Some(ty_iri) } } - literal::Type::LangString(_) => { + LiteralTypeRef::LangString(_) => { literal_ty = Some($crate::rdf_types::RDF_LANG_STRING) } } diff --git a/linked-data/src/predicate.rs b/src/predicate.rs similarity index 88% rename from linked-data/src/predicate.rs rename to src/predicate.rs index 2834ae8..1d401a8 100644 --- a/linked-data/src/predicate.rs +++ b/src/predicate.rs @@ -1,8 +1,11 @@ use iref::{Iri, IriBuf}; use rdf_types::{ - interpretation::{ReverseBlankIdInterpretation, ReverseIriInterpretation}, - BlankId, BlankIdBuf, BlankIdVocabularyMut, Id, Interpretation, IriVocabularyMut, - ReverseIdInterpretation, Vocabulary, + dataset::PatternMatchingDataset, + interpretation::{ + ReverseBlankIdInterpretation, ReverseIdInterpretation, ReverseIriInterpretation, + }, + vocabulary::{BlankIdVocabularyMut, IriVocabularyMut}, + BlankId, BlankIdBuf, Id, Interpretation, Vocabulary, }; use crate::{ @@ -179,34 +182,24 @@ pub trait LinkedDataDeserializePredicateObjects, objects: impl IntoIterator, context: Context, ) -> Result where I::Resource: 'a, - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >; + D: PatternMatchingDataset; fn deserialize_objects<'a, D>( vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, objects: impl IntoIterator, ) -> Result where I::Resource: 'a, - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { Self::deserialize_objects_in( vocabulary, @@ -225,18 +218,13 @@ macro_rules! deserialize_single_object { vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, objects: impl IntoIterator, context: $crate::Context, ) -> Result where I::Resource: 'a, - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { use crate::LinkedDataDeserializeSubject; let mut objects = objects.into_iter(); @@ -293,18 +281,13 @@ impl, objects: impl IntoIterator, context: Context, ) -> Result where I::Resource: 'a, - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { T::deserialize_objects_in(vocabulary, interpretation, dataset, graph, objects, context) .map(Box::new) @@ -320,18 +303,13 @@ where vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, objects: impl IntoIterator, context: Context, ) -> Result where I::Resource: 'a, - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { let mut objects = objects.into_iter(); match objects.next() { diff --git a/linked-data/src/quads.rs b/src/quads.rs similarity index 92% rename from linked-data/src/quads.rs rename to src/quads.rs index a3686ff..645d883 100644 --- a/linked-data/src/quads.rs +++ b/src/quads.rs @@ -1,17 +1,21 @@ use educe::Educe; use iref::IriBuf; use rdf_types::{ - interpretation::{self, ReverseBlankIdInterpretation, ReverseIriInterpretation}, - BlankIdInterpretationMut, ExportedFromVocabulary, Generator, Id, InsertIntoVocabulary, - Interpretation, InterpretationMut, IriInterpretationMut, IriVocabularyMut, - LiteralInterpretationMut, LiteralVocabularyMut, Quad, ReverseLiteralInterpretation, - ReverseTermInterpretation, Term, Vocabulary, + interpretation::{ + self, BlankIdInterpretationMut, IriInterpretationMut, LiteralInterpretationMut, + ReverseBlankIdInterpretation, ReverseIriInterpretation, ReverseTermInterpretation, + TermInterpretationMut, + }, + vocabulary::{ + EmbedIntoVocabulary, ExtractedFromVocabulary, IriVocabularyMut, LiteralVocabularyMut, + }, + Generator, Id, Interpretation, InterpretationMut, Quad, Term, Vocabulary, }; use crate::{ CowRdfTerm, GraphVisitor, InterpretedQuad, LinkedData, LinkedDataGraph, LinkedDataResource, - LinkedDataSubject, PredicateObjectsVisitor, RdfId, RdfLiteralType, RdfLiteralValue, RdfQuad, - ResourceInterpretation, SubjectVisitor, Visitor, + LinkedDataSubject, PredicateObjectsVisitor, RdfId, RdfQuad, ResourceInterpretation, + SubjectVisitor, Visitor, }; pub fn to_interpreted_quads( @@ -20,17 +24,11 @@ pub fn to_interpreted_quads( value: &impl LinkedData, ) -> Result>, IntoQuadsError> where - I: InterpretationMut - + IriInterpretationMut - + BlankIdInterpretationMut - + LiteralInterpretationMut, + I: InterpretationMut + TermInterpretationMut, I::Resource: Clone, V: IriVocabularyMut + LiteralVocabularyMut, V::Iri: Clone, V::BlankId: Clone, - V::Value: RdfLiteralValue, - V::Type: RdfLiteralType, - V::LanguageTag: Clone, { value.visit(QuadSerializer { vocabulary, @@ -55,9 +53,6 @@ where V: IriVocabularyMut + LiteralVocabularyMut, V::Iri: Clone, V::BlankId: Clone, - V::Value: RdfLiteralValue, - V::Type: RdfLiteralType, - V::LanguageTag: Clone, { let mut result = Vec::new(); @@ -92,9 +87,6 @@ where V: IriVocabularyMut + LiteralVocabularyMut, V::Iri: Clone, V::BlankId: Clone, - V::Value: RdfLiteralValue, - V::Type: RdfLiteralType, - V::LanguageTag: Clone, { let mut result = Vec::new(); @@ -118,13 +110,11 @@ pub fn to_lexical_quads_with( vocabulary: &mut V, interpretation: &mut I, value: &impl LinkedData, -) -> Result, IntoQuadsError> +) -> Result, IntoQuadsError> where I: InterpretationMut - + ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, - V::Literal: ExportedFromVocabulary, + + ReverseTermInterpretation, + V::Literal: ExtractedFromVocabulary, { let mut domain = LexicalDomain; @@ -141,14 +131,12 @@ pub fn to_lexical_subject_quads_with( interpretation: &mut I, graph: Option<&Id>, value: &(impl LinkedDataSubject + LinkedDataResource), -) -> Result<(Id, Vec), IntoQuadsError> +) -> Result<(Id, Vec), IntoQuadsError> where I: InterpretationMut - + ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, + + ReverseTermInterpretation, I::Resource: Clone, - V::Literal: ExportedFromVocabulary, + V::Literal: ExtractedFromVocabulary, { let mut result = Vec::new(); @@ -170,7 +158,7 @@ where pub fn to_lexical_quads( generator: G, value: &impl LinkedData>, -) -> Result, IntoQuadsError> { +) -> Result, IntoQuadsError> { let mut interpretation = rdf_types::interpretation::WithGenerator::new((), generator); to_lexical_quads_with(&mut (), &mut interpretation, value) } @@ -180,7 +168,7 @@ pub fn to_lexical_subject_quads( graph: Option<&Id>, value: &(impl LinkedDataSubject> + LinkedDataResource>), -) -> Result<(Id, Vec), IntoQuadsError> { +) -> Result<(Id, Vec), IntoQuadsError> { let mut interpretation = rdf_types::interpretation::WithGenerator::new((), generator); to_lexical_subject_quads_with(&mut (), &mut interpretation, graph, value) } @@ -195,12 +183,7 @@ where V::BlankId: Clone, V::Iri: Clone, V::Literal: Clone, - V::Value: RdfLiteralValue, - V::Type: RdfLiteralType, - V::LanguageTag: Clone, - I: ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, + I: ReverseTermInterpretation, { let mut domain = VocabularyDomain; @@ -215,7 +198,7 @@ where pub fn to_quads( generator: G, value: &impl LinkedData>, -) -> Result, IntoQuadsError> { +) -> Result, IntoQuadsError> { let mut interpretation = interpretation::WithGenerator::new((), generator); to_quads_with(&mut (), &mut interpretation, value) } @@ -345,12 +328,7 @@ where V::Iri: Clone, V::BlankId: Clone, V::Literal: Clone, - V::Value: RdfLiteralValue, - V::Type: RdfLiteralType, - V::LanguageTag: Clone, - I: ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, + I: ReverseTermInterpretation, { type Subject = RdfId; type Predicate = V::Iri; @@ -420,11 +398,11 @@ where let term = match u { Some(CowRdfTerm::Owned(Term::Id(id))) => Term::Id(id), Some(CowRdfTerm::Owned(Term::Literal(l))) => { - Term::Literal(l.insert_into_vocabulary(vocabulary)) + Term::Literal(l.embed_into_vocabulary(vocabulary)) } Some(CowRdfTerm::Borrowed(Term::Id(id))) => Term::Id(id.cloned()), Some(CowRdfTerm::Borrowed(Term::Literal(l))) => { - Term::Literal(l.into_owned().insert_into_vocabulary(vocabulary)) + Term::Literal(l.into_owned().embed_into_vocabulary(vocabulary)) } None => { let r = interpretation.new_resource(vocabulary); @@ -522,9 +500,6 @@ where V: IriVocabularyMut + LiteralVocabularyMut, V::Iri: Clone, V::BlankId: Clone, - V::Value: RdfLiteralValue, - V::Type: RdfLiteralType, - V::LanguageTag: Clone, { type Subject = I::Resource; type Predicate = I::Resource; @@ -601,12 +576,12 @@ where Ok(interpretation.interpret_blank_id(b.clone())) } Some(CowRdfTerm::Owned(Term::Literal(l))) => { - let l = l.insert_into_vocabulary(vocabulary); + let l = l.embed_into_vocabulary(vocabulary); let l = interpretation.interpret_literal(l); Ok(l) } Some(CowRdfTerm::Borrowed(Term::Literal(l))) => { - let l = l.into_owned().insert_into_vocabulary(vocabulary); + let l = l.into_owned().embed_into_vocabulary(vocabulary); let l = interpretation.interpret_literal(l); Ok(l) } @@ -711,7 +686,7 @@ fn resource_lexical_term( r: &I::Resource, ) -> Result, IntoQuadsError> where - V::Literal: ExportedFromVocabulary, + V::Literal: ExtractedFromVocabulary, I: ReverseTermInterpretation, { if let Some(iri) = interpretation.iris_of(r).next() { @@ -733,10 +708,8 @@ where impl, V: Vocabulary> Domain for LexicalDomain where - I: ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, - V::Literal: ExportedFromVocabulary, + I: ReverseTermInterpretation, + V::Literal: ExtractedFromVocabulary, { type Subject = Id; type Predicate = IriBuf; diff --git a/linked-data/src/rdf.rs b/src/rdf.rs similarity index 56% rename from linked-data/src/rdf.rs rename to src/rdf.rs index 6c54bf4..0e4f772 100644 --- a/linked-data/src/rdf.rs +++ b/src/rdf.rs @@ -4,9 +4,11 @@ use std::borrow::Borrow; use educe::Educe; use iref::Iri; use rdf_types::{ - literal, BlankIdVocabulary, Id, InsertIntoVocabulary, Interpretation, IriVocabulary, - IriVocabularyMut, LanguageTagVocabulary, LiteralVocabulary, LiteralVocabularyMut, Quad, Term, - Vocabulary, + vocabulary::{ + BlankIdVocabulary, EmbedIntoVocabulary, IriVocabulary, IriVocabularyMut, LiteralVocabulary, + LiteralVocabularyMut, + }, + Id, Interpretation, LiteralType, LiteralTypeRef, Quad, Term, Vocabulary, }; pub type RdfId = Id<::Iri, ::BlankId>; @@ -15,22 +17,17 @@ pub type RdfTerm = Term, RdfLiteral>; pub type RdfIdRef<'a, V> = Id<&'a ::Iri, &'a ::BlankId>; pub type RdfTermRef<'a, V> = Term, RdfLiteralRef<'a, V>>; -pub type RdfQuad = Quad< +pub type RdfQuad = Quad< RdfId, ::Iri, Term, ::Literal>, RdfId, >; -pub type InterpretedQuad = Quad< - ::Resource, - ::Resource, - ::Resource, - ::Resource, ->; +pub type InterpretedQuad = Quad<::Resource>; #[derive(Educe)] -#[educe(Debug(bound = "V::Iri: fmt::Debug, V::BlankId: fmt::Debug, V::LanguageTag: fmt::Debug"))] +#[educe(Debug(bound = "V::Iri: fmt::Debug, V::BlankId: fmt::Debug"))] pub enum CowRdfTerm<'a, V: Vocabulary> { Borrowed(RdfTermRef<'a, V>), Owned(RdfTerm), @@ -48,7 +45,7 @@ impl<'a, V: Vocabulary> CowRdfTerm<'a, V> { Ok((json, _)) => CowRdfTerm::Owned(RdfTerm::Literal(RdfLiteral::Json(json))), Err(_) => CowRdfTerm::Borrowed(RdfTermRef::Literal(RdfLiteralRef::Any( value, - literal::Type::Any(ty), + LiteralTypeRef::Any(ty), ))), } } else { @@ -64,12 +61,12 @@ impl<'a, V: Vocabulary> CowRdfTerm<'a, V> { } Err(_) => CowRdfTerm::Borrowed(RdfTermRef::Literal(RdfLiteralRef::Any( value, - literal::Type::Any(ty), + LiteralTypeRef::Any(ty), ))), }, None => CowRdfTerm::Borrowed(RdfTermRef::Literal(RdfLiteralRef::Any( value, - literal::Type::Any(ty), + LiteralTypeRef::Any(ty), ))), } } @@ -129,7 +126,6 @@ impl<'a, V: Vocabulary> CowRdfTerm<'a, V> { where V::Iri: Clone, V::BlankId: Clone, - V::LanguageTag: Clone, { match self { Self::Borrowed(t) => match t { @@ -149,91 +145,77 @@ pub trait RdfLiteralValue: impl + From + From> RdfLiteralValue for T {} -pub trait AsRdfLiteral> { - fn as_rdf_literal<'a>(&'a self, vocabulary: &V, ty: &'a V::Type) -> CowRdfLiteral; +pub trait AsRdfLiteral { + fn as_rdf_literal<'a>( + &'a self, + vocabulary: &V, + ty: LiteralTypeRef<'a, V::Iri>, + ) -> CowRdfLiteral; } -impl< - V: IriVocabulary - + LanguageTagVocabulary - + LiteralVocabulary>, - > AsRdfLiteral for String -{ +impl AsRdfLiteral for str { fn as_rdf_literal<'a>( &'a self, _vocabulary: &V, - ty: &'a ::Type, + ty: LiteralTypeRef<'a, V::Iri>, ) -> CowRdfLiteral { - let ty = match ty { - literal::Type::Any(i) => literal::Type::Any(i), - literal::Type::LangString(t) => literal::Type::LangString(t), - }; - CowRdfLiteral::Borrowed(RdfLiteralRef::Any(self, ty)) } } -pub trait RdfLiteralType: - From> -{ +impl AsRdfLiteral for String { + fn as_rdf_literal<'a>( + &'a self, + vocabulary: &V, + ty: LiteralTypeRef<'a, V::Iri>, + ) -> CowRdfLiteral { + self.as_str().as_rdf_literal(vocabulary, ty) + } } -impl< - V: IriVocabulary + LanguageTagVocabulary, - T: From>, - > RdfLiteralType for T -{ -} +pub trait RdfLiteralType: From> {} + +impl>> RdfLiteralType for T {} #[derive(Educe)] -#[educe(Debug(bound = "V::Iri: fmt::Debug, V::LanguageTag: fmt::Debug"))] -pub enum RdfLiteral { - Any(String, rdf_types::literal::Type), +#[educe(Debug(bound = "V::Iri: fmt::Debug"))] +pub enum RdfLiteral { + Any(String, rdf_types::LiteralType), Xsd(xsd_types::Value), Json(json_syntax::Value), } -impl RdfLiteral { +impl RdfLiteral { pub fn into_lexical(self, vocabulary: &V) -> rdf_types::Literal { match self { - Self::Any(s, literal::Type::Any(ty)) => rdf_types::Literal::new( + Self::Any(s, LiteralType::Any(ty)) => rdf_types::Literal::new( s.to_owned(), - literal::Type::Any(vocabulary.owned_iri(ty).ok().unwrap()), - ), - Self::Any(s, literal::Type::LangString(lang)) => rdf_types::Literal::new( - s.to_owned(), - literal::Type::LangString(vocabulary.owned_language_tag(lang).ok().unwrap()), + LiteralType::Any(vocabulary.owned_iri(ty).ok().unwrap()), ), + Self::Any(s, LiteralType::LangString(lang)) => { + rdf_types::Literal::new(s.to_owned(), LiteralType::LangString(lang)) + } Self::Xsd(value) => { let ty = value.datatype().iri().to_owned(); - rdf_types::Literal::new(value.to_string(), literal::Type::Any(ty)) + rdf_types::Literal::new(value.to_string(), LiteralType::Any(ty)) } Self::Json(mut value) => { value.canonicalize(); - rdf_types::Literal::new(value.to_string(), literal::Type::Any(RDF_JSON.to_owned())) + rdf_types::Literal::new(value.to_string(), LiteralType::Any(RDF_JSON.to_owned())) } } } pub fn as_literal_ref(&self) -> RdfLiteralRef { match self { - Self::Any(value, ty) => { - let ty = match ty { - rdf_types::literal::Type::Any(i) => rdf_types::literal::Type::Any(i), - rdf_types::literal::Type::LangString(t) => { - rdf_types::literal::Type::LangString(t) - } - }; - - RdfLiteralRef::Any(value, ty) - } + Self::Any(value, ty) => RdfLiteralRef::Any(value, ty.as_ref()), Self::Xsd(value) => RdfLiteralRef::Xsd(value.as_ref()), Self::Json(value) => RdfLiteralRef::Json(value), } } } -impl fmt::Display for RdfLiteral { +impl fmt::Display for RdfLiteral { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Any(v, _) => v.fmt(f), @@ -245,65 +227,52 @@ impl fmt::Display for RdfLiteral { const RDF_JSON: &Iri = static_iref::iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#JSON"); -impl InsertIntoVocabulary +impl EmbedIntoVocabulary for RdfLiteral -where - V::Value: From + From + From, - V::Type: From>, { - type Inserted = V::Literal; + type Embedded = V::Literal; - fn insert_into_vocabulary(self, vocabulary: &mut V) -> V::Literal { + fn embed_into_vocabulary(self, vocabulary: &mut V) -> V::Literal { match self { - Self::Any(s, ty) => { - vocabulary.insert_owned_literal(rdf_types::Literal::new(s.into(), ty.into())) - } + Self::Any(s, ty) => vocabulary.insert_owned_literal(rdf_types::Literal::new(s, ty)), Self::Xsd(v) => { - let ty = rdf_types::literal::Type::Any(vocabulary.insert(v.datatype().iri())); - vocabulary.insert_owned_literal(rdf_types::Literal::new(v.into(), ty.into())) + let ty = rdf_types::LiteralType::Any(vocabulary.insert(v.datatype().iri())); + vocabulary.insert_owned_literal(rdf_types::Literal::new(v.into(), ty)) } Self::Json(v) => { - let ty = rdf_types::literal::Type::Any(vocabulary.insert(RDF_JSON)); - vocabulary.insert_owned_literal(rdf_types::Literal::new(v.into(), ty.into())) + let ty = rdf_types::LiteralType::Any(vocabulary.insert(RDF_JSON)); + vocabulary.insert_owned_literal(rdf_types::Literal::new(v.into(), ty)) } } } } #[derive(Educe)] -#[educe( - Debug(bound = "V::Iri: fmt::Debug, V::LanguageTag: fmt::Debug"), - Clone, - Copy -)] -pub enum RdfLiteralRef<'a, V: IriVocabulary + LanguageTagVocabulary = ()> { - Any( - &'a str, - rdf_types::literal::Type<&'a V::Iri, &'a V::LanguageTag>, - ), +#[educe(Debug(bound = "V::Iri: fmt::Debug"), Clone, Copy)] +pub enum RdfLiteralRef<'a, V: IriVocabulary = ()> { + Any(&'a str, rdf_types::LiteralTypeRef<'a, V::Iri>), Xsd(xsd_types::ValueRef<'a>), Json(&'a json_syntax::Value), } -impl<'a, V: IriVocabulary + LanguageTagVocabulary> RdfLiteralRef<'a, V> { +impl<'a, V: IriVocabulary> RdfLiteralRef<'a, V> { pub fn into_lexical(self, vocabulary: &V) -> rdf_types::Literal { match self { - Self::Any(s, literal::Type::Any(ty)) => rdf_types::Literal::new( + Self::Any(s, LiteralTypeRef::Any(ty)) => rdf_types::Literal::new( s.to_owned(), - literal::Type::Any(vocabulary.iri(ty).unwrap().to_owned()), - ), - Self::Any(s, literal::Type::LangString(lang)) => rdf_types::Literal::new( - s.to_owned(), - literal::Type::LangString(vocabulary.language_tag(lang).unwrap().cloned()), + LiteralType::Any(vocabulary.iri(ty).unwrap().to_owned()), ), + Self::Any(s, LiteralTypeRef::LangString(lang)) => { + rdf_types::Literal::new(s.to_owned(), LiteralType::LangString(lang.to_owned())) + } Self::Xsd(value) => { let ty = value.datatype().iri().to_owned(); - rdf_types::Literal::new(value.to_string(), literal::Type::Any(ty)) + rdf_types::Literal::new(value.to_string(), LiteralType::Any(ty)) } Self::Json(value) => { let mut value = value.clone(); value.canonicalize(); - rdf_types::Literal::new(value.to_string(), literal::Type::Any(RDF_JSON.to_owned())) + rdf_types::Literal::new(value.to_string(), LiteralType::Any(RDF_JSON.to_owned())) } } } @@ -311,37 +280,24 @@ impl<'a, V: IriVocabulary + LanguageTagVocabulary> RdfLiteralRef<'a, V> { pub fn into_owned(self) -> RdfLiteral where V::Iri: Clone, - V::LanguageTag: Clone, { match self { - Self::Any(value, ty) => { - let ty = match ty { - rdf_types::literal::Type::Any(iri) => { - rdf_types::literal::Type::Any(iri.clone()) - } - rdf_types::literal::Type::LangString(tag) => { - rdf_types::literal::Type::LangString(tag.clone()) - } - }; - - RdfLiteral::Any(value.to_owned(), ty) - } + Self::Any(value, ty) => RdfLiteral::Any(value.to_owned(), ty.into_owned()), Self::Xsd(value) => RdfLiteral::Xsd(value.into_owned()), Self::Json(value) => RdfLiteral::Json(value.clone()), } } } -pub enum CowRdfLiteral<'a, V: IriVocabulary + LanguageTagVocabulary = ()> { +pub enum CowRdfLiteral<'a, V: IriVocabulary = ()> { Borrowed(RdfLiteralRef<'a, V>), Owned(RdfLiteral), } -impl<'a, V: IriVocabulary + LanguageTagVocabulary> CowRdfLiteral<'a, V> { +impl<'a, V: IriVocabulary> CowRdfLiteral<'a, V> { pub fn into_owned(self) -> RdfLiteral where V::Iri: Clone, - V::LanguageTag: Clone, { match self { Self::Borrowed(l) => l.into_owned(), diff --git a/linked-data/src/reference.rs b/src/reference.rs similarity index 100% rename from linked-data/src/reference.rs rename to src/reference.rs diff --git a/linked-data/src/resource.rs b/src/resource.rs similarity index 84% rename from linked-data/src/resource.rs rename to src/resource.rs index b8d5fd6..d741dff 100644 --- a/linked-data/src/resource.rs +++ b/src/resource.rs @@ -1,9 +1,9 @@ use educe::Educe; use iref::{Iri, IriBuf}; use rdf_types::{ - interpretation::{ReverseBlankIdInterpretation, ReverseIriInterpretation}, - BlankId, BlankIdBuf, BlankIdVocabularyMut, Id, Interpretation, IriVocabularyMut, - ReverseLiteralInterpretation, Term, Vocabulary, + interpretation::ReverseTermInterpretation, + vocabulary::{BlankIdVocabularyMut, IriVocabularyMut}, + BlankId, BlankIdBuf, Id, Interpretation, Term, Vocabulary, }; use std::fmt; @@ -11,9 +11,7 @@ use crate::{AsRdfLiteral, CowRdfTerm}; /// Resource interpretation. #[derive(Educe)] -#[educe(Debug( - bound = "I::Resource: fmt::Debug, V::Iri: fmt::Debug, V::BlankId: fmt::Debug, V::LanguageTag: fmt::Debug" -))] +#[educe(Debug(bound = "I::Resource: fmt::Debug, V::Iri: fmt::Debug, V::BlankId: fmt::Debug"))] pub enum ResourceInterpretation<'a, I: Interpretation, V: Vocabulary> { /// Interpreted resource. Interpreted(&'a I::Resource), @@ -46,10 +44,7 @@ impl<'a, I: Interpretation, V: Vocabulary> ResourceInterpretation<'a, I, V> { interpretation: &'a I, ) -> Option> where - V::Value: AsRdfLiteral, - I: ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, + I: ReverseTermInterpretation, { match self { Self::Interpreted(r) => { @@ -59,7 +54,7 @@ impl<'a, I: Interpretation, V: Vocabulary> ResourceInterpretation<'a, I, V> { if let Some(l) = interpretation.literals_of(r).next() { let l = vocabulary.literal(l).unwrap(); - let term = match l.value().as_rdf_literal(vocabulary, l.type_()) { + let term = match l.value.as_rdf_literal(vocabulary, l.type_) { crate::CowRdfLiteral::Borrowed(l) => CowRdfTerm::Borrowed(Term::Literal(l)), crate::CowRdfLiteral::Owned(l) => CowRdfTerm::Owned(Term::Literal(l)), }; @@ -101,10 +96,7 @@ pub trait LinkedDataResource { interpretation: &'a mut I, ) -> Option> where - V::Value: AsRdfLiteral, - I: ReverseIriInterpretation - + ReverseBlankIdInterpretation - + ReverseLiteralInterpretation, + I: ReverseTermInterpretation, { self.interpretation(vocabulary, interpretation) .into_lexical_representation(vocabulary, interpretation) @@ -258,21 +250,14 @@ impl< } } -impl> LinkedDataResource - for rdf_types::Literal, S> -{ +impl LinkedDataResource for rdf_types::Literal { fn interpretation( &self, _vocabulary: &mut V, _interpretation: &mut I, ) -> ResourceInterpretation { - let ty = match self.type_() { - rdf_types::literal::Type::Any(i) => rdf_types::literal::Type::Any(i), - rdf_types::literal::Type::LangString(l) => rdf_types::literal::Type::LangString(l), - }; - ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(Term::Literal( - crate::RdfLiteralRef::Any(self.value().as_ref(), ty), + crate::RdfLiteralRef::Any(self.value.as_ref(), self.type_.as_ref()), )))) } } diff --git a/linked-data/src/subject.rs b/src/subject.rs similarity index 87% rename from linked-data/src/subject.rs rename to src/subject.rs index 636564d..ed10871 100644 --- a/linked-data/src/subject.rs +++ b/src/subject.rs @@ -1,7 +1,10 @@ use iref::{Iri, IriBuf}; use rdf_types::{ - interpretation::{ReverseBlankIdInterpretation, ReverseIriInterpretation}, - BlankId, BlankIdBuf, Id, Interpretation, ReverseIdInterpretation, Vocabulary, + dataset::PatternMatchingDataset, + interpretation::{ + ReverseBlankIdInterpretation, ReverseIdInterpretation, ReverseIriInterpretation, + }, + BlankId, BlankIdBuf, Id, Interpretation, Vocabulary, }; use crate::{ @@ -171,32 +174,22 @@ pub trait LinkedDataDeserializeSubject, resource: &I::Resource, context: Context, ) -> Result where - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >; + D: PatternMatchingDataset; fn deserialize_subject( vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, resource: &I::Resource, ) -> Result where - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { Self::deserialize_subject_in( vocabulary, @@ -217,17 +210,12 @@ where vocabulary: &V, interpretation: &I, _dataset: &D, - _graph: &D::Graph, + _graph: Option<&I::Resource>, resource: &I::Resource, context: Context, ) -> Result where - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { match interpretation.iris_of(resource).next() { Some(i) => { @@ -250,17 +238,12 @@ where vocabulary: &V, interpretation: &I, _dataset: &D, - _graph: &D::Graph, + _graph: Option<&I::Resource>, resource: &I::Resource, context: Context, ) -> Result where - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { match interpretation.blank_ids_of(resource).next() { Some(b) => { @@ -286,17 +269,12 @@ where vocabulary: &V, interpretation: &I, _dataset: &D, - _graph: &D::Graph, + _graph: Option<&I::Resource>, resource: &I::Resource, context: Context, ) -> Result where - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { match interpretation.ids_of(resource).next() { Some(Id::Iri(i)) => { @@ -322,17 +300,12 @@ impl> vocabulary: &V, interpretation: &I, dataset: &D, - graph: &D::Graph, + graph: Option<&I::Resource>, resource: &I::Resource, context: Context, ) -> Result where - D: grdf::Dataset< - Subject = I::Resource, - Predicate = I::Resource, - Object = I::Resource, - GraphLabel = I::Resource, - >, + D: PatternMatchingDataset, { T::deserialize_subject_in( vocabulary,