Cleans up code related to file syntaxes

pull/46/head
Tpt 4 years ago
parent 0d4743f452
commit 9d4fe700d6
  1. 6
      js/src/store.rs
  2. 6
      lib/src/io/mod.rs
  3. 136
      lib/src/io/syntax.rs
  4. 12
      lib/src/lib.rs
  5. 67
      lib/src/sparql/model.rs
  6. 6
      python/src/memory_store.rs
  7. 6
      python/src/sled_store.rs
  8. 17
      server/src/main.rs
  9. 12
      wikibase/src/main.rs

@ -4,7 +4,7 @@ use crate::utils::to_err;
use js_sys::{Array, Map};
use oxigraph::model::GraphName;
use oxigraph::sparql::{QueryOptions, QueryResult};
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, MemoryStore};
use oxigraph::{DatasetSyntax, GraphSyntax, MemoryStore};
use std::convert::TryInto;
use std::io::Cursor;
use wasm_bindgen::prelude::*;
@ -157,7 +157,7 @@ impl JsMemoryStore {
None
};
if let Some(graph_syntax) = GraphSyntax::from_mime_type(mime_type) {
if let Some(graph_syntax) = GraphSyntax::from_media_type(mime_type) {
self.store
.load_graph(
Cursor::new(data),
@ -166,7 +166,7 @@ impl JsMemoryStore {
base_iri.as_deref(),
)
.map_err(to_err)
} else if let Some(dataset_syntax) = DatasetSyntax::from_mime_type(mime_type) {
} else if let Some(dataset_syntax) = DatasetSyntax::from_media_type(mime_type) {
if to_graph_name.is_some() {
return Err(format_err!(
"The target graph name parameter is not available for dataset formats"

@ -0,0 +1,6 @@
mod syntax;
pub use self::syntax::DatasetSyntax;
#[allow(deprecated)]
pub use self::syntax::FileSyntax;
pub use self::syntax::GraphSyntax;

@ -1,8 +1,9 @@
/// A file serialization format.
///
/// Is implemented by `GraphSyntax` for graph files and `DatasetSyntax` for dataset files.
#[deprecated(note = "Use directly the methods on the implementing types")]
pub trait FileSyntax: Sized {
/// Its canonical IRI according to [Unique URIs for file formats registry](https://www.w3.org/ns/formats/).
/// Its canonical IRI according to the [Unique URIs for file formats registry](https://www.w3.org/ns/formats/).
fn iri(self) -> &'static str;
/// Its [IANA media type](https://tools.ietf.org/html/rfc2046).
@ -12,12 +13,6 @@ pub trait FileSyntax: Sized {
fn file_extension(self) -> &'static str;
/// Looks for a known syntax from a media type.
///
/// Example:
/// ```
/// use oxigraph::{GraphSyntax, FileSyntax};
/// assert_eq!(GraphSyntax::from_mime_type("text/turtle; charset=utf-8"), Some(GraphSyntax::Turtle))
/// ```
fn from_mime_type(media_type: &str) -> Option<Self>;
}
@ -32,8 +27,15 @@ pub enum GraphSyntax {
RdfXml,
}
impl FileSyntax for GraphSyntax {
fn iri(self) -> &'static str {
impl GraphSyntax {
/// The syntax canonical IRI according to the [Unique URIs for file formats registry](https://www.w3.org/ns/formats/).
///
/// ```
/// use oxigraph::io::GraphSyntax;
///
/// assert_eq!(GraphSyntax::NTriples.iri(), "http://www.w3.org/ns/formats/N-Triples")
/// ```
pub fn iri(self) -> &'static str {
match self {
GraphSyntax::NTriples => "http://www.w3.org/ns/formats/N-Triples",
GraphSyntax::Turtle => "http://www.w3.org/ns/formats/Turtle",
@ -41,7 +43,14 @@ impl FileSyntax for GraphSyntax {
}
}
fn media_type(self) -> &'static str {
/// The syntax [IANA media type](https://tools.ietf.org/html/rfc2046).
///
/// ```
/// use oxigraph::io::GraphSyntax;
///
/// assert_eq!(GraphSyntax::NTriples.media_type(), "application/n-triples")
/// ```
pub fn media_type(self) -> &'static str {
match self {
GraphSyntax::NTriples => "application/n-triples",
GraphSyntax::Turtle => "text/turtle",
@ -49,17 +58,34 @@ impl FileSyntax for GraphSyntax {
}
}
fn file_extension(self) -> &'static str {
/// The syntax [IANA-registered](https://tools.ietf.org/html/rfc2046) file extension.
///
/// ```
/// use oxigraph::io::GraphSyntax;
///
/// assert_eq!(GraphSyntax::NTriples.file_extension(), "nt")
/// ```
pub fn file_extension(self) -> &'static str {
match self {
GraphSyntax::NTriples => "nt",
GraphSyntax::Turtle => "ttl",
GraphSyntax::RdfXml => "rdf",
}
}
fn from_mime_type(media_type: &str) -> Option<Self> {
/// Looks for a known syntax from a media type.
///
/// It supports some media type aliases.
/// For example "application/xml" is going to return `GraphSyntax::RdfXml` even if it is not its canonical media type.
///
/// Example:
/// ```
/// use oxigraph::io::GraphSyntax;
///
/// assert_eq!(GraphSyntax::from_media_type("text/turtle; charset=utf-8"), Some(GraphSyntax::Turtle))
/// ```
pub fn from_media_type(media_type: &str) -> Option<Self> {
if let Some(base_type) = media_type.split(';').next() {
match base_type {
match base_type.trim() {
"application/n-triples" | "text/plain" => Some(GraphSyntax::NTriples),
"text/turtle" | "application/turtle" | "application/x-turtle" => {
Some(GraphSyntax::Turtle)
@ -73,6 +99,25 @@ impl FileSyntax for GraphSyntax {
}
}
#[allow(deprecated)]
impl FileSyntax for GraphSyntax {
fn iri(self) -> &'static str {
self.iri()
}
fn media_type(self) -> &'static str {
self.media_type()
}
fn file_extension(self) -> &'static str {
self.file_extension()
}
fn from_mime_type(media_type: &str) -> Option<Self> {
Self::from_media_type(media_type)
}
}
/// [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) serialization formats.
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum DatasetSyntax {
@ -82,31 +127,61 @@ pub enum DatasetSyntax {
TriG,
}
impl FileSyntax for DatasetSyntax {
fn iri(self) -> &'static str {
impl DatasetSyntax {
/// The syntax canonical IRI according to the [Unique URIs for file formats registry](https://www.w3.org/ns/formats/).
///
/// ```
/// use oxigraph::io::DatasetSyntax;
///
/// assert_eq!(DatasetSyntax::NQuads.iri(), "http://www.w3.org/ns/formats/N-Quads")
/// ```
pub fn iri(self) -> &'static str {
match self {
DatasetSyntax::NQuads => "http://www.w3.org/ns/formats/N-Quads",
DatasetSyntax::TriG => "http://www.w3.org/ns/formats/TriG",
}
}
fn media_type(self) -> &'static str {
/// The syntax [IANA media type](https://tools.ietf.org/html/rfc2046).
///
/// ```
/// use oxigraph::io::DatasetSyntax;
///
/// assert_eq!(DatasetSyntax::NQuads.media_type(), "application/n-quads")
/// ```
pub fn media_type(self) -> &'static str {
match self {
DatasetSyntax::NQuads => "application/n-quads",
DatasetSyntax::TriG => "application/trig",
}
}
fn file_extension(self) -> &'static str {
/// The syntax [IANA-registered](https://tools.ietf.org/html/rfc2046) file extension.
///
/// ```
/// use oxigraph::io::DatasetSyntax;
///
/// assert_eq!(DatasetSyntax::NQuads.file_extension(), "nq")
/// ```
pub fn file_extension(self) -> &'static str {
match self {
DatasetSyntax::NQuads => "nq",
DatasetSyntax::TriG => "trig",
}
}
fn from_mime_type(media_type: &str) -> Option<Self> {
/// Looks for a known syntax from a media type.
///
/// It supports some media type aliases.
///
/// Example:
/// ```
/// use oxigraph::io::DatasetSyntax;
///
/// assert_eq!(DatasetSyntax::from_media_type("application/n-quads; charset=utf-8"), Some(DatasetSyntax::NQuads))
/// ```
pub fn from_media_type(media_type: &str) -> Option<Self> {
if let Some(base_type) = media_type.split(';').next() {
match base_type {
match base_type.trim() {
"application/n-quads" | "text/x-nquads" | "text/nquads" => {
Some(DatasetSyntax::NQuads)
}
@ -118,3 +193,22 @@ impl FileSyntax for DatasetSyntax {
}
}
}
#[allow(deprecated)]
impl FileSyntax for DatasetSyntax {
fn iri(self) -> &'static str {
self.iri()
}
fn media_type(self) -> &'static str {
self.media_type()
}
fn file_extension(self) -> &'static str {
self.file_extension()
}
fn from_mime_type(media_type: &str) -> Option<Self> {
Self::from_media_type(media_type)
}
}

@ -104,18 +104,22 @@
#![doc(test(attr(deny(warnings))))]
mod error;
pub mod io;
pub mod model;
pub mod sparql;
pub mod store;
mod syntax;
pub use error::Error;
pub type Result<T> = ::std::result::Result<T, Error>;
#[deprecated(note = "Use oxigraph::io::DatasetSyntax instead")]
pub use crate::io::DatasetSyntax;
#[deprecated(note = "Use oxigraph::io::FileSyntax instead")]
#[allow(deprecated)]
pub use crate::io::FileSyntax;
#[deprecated(note = "Use oxigraph::io::GraphSyntax instead")]
pub use crate::io::GraphSyntax;
pub use crate::store::memory::MemoryStore;
#[cfg(feature = "rocksdb")]
pub use crate::store::rocksdb::RocksDbStore;
#[cfg(feature = "sled")]
pub use crate::store::sled::SledStore;
pub use crate::syntax::DatasetSyntax;
pub use crate::syntax::FileSyntax;
pub use crate::syntax::GraphSyntax;

@ -1,8 +1,9 @@
#[allow(deprecated)]
use crate::io::{FileSyntax, GraphSyntax};
use crate::model::*;
use crate::sparql::json_results::write_json_results;
use crate::sparql::xml_results::{read_xml_results, write_xml_results};
use crate::Error;
use crate::{FileSyntax, GraphSyntax, Result};
use crate::{Error, Result};
use rand::random;
use rio_api::formatter::TriplesFormatter;
use rio_turtle::{NTriplesFormatter, TurtleFormatter};
@ -120,29 +121,60 @@ pub enum QueryResultSyntax {
Json,
}
impl FileSyntax for QueryResultSyntax {
fn iri(self) -> &'static str {
impl QueryResultSyntax {
/// The syntax canonical IRI according to the [Unique URIs for file formats registry](https://www.w3.org/ns/formats/).
///
/// ```
/// use oxigraph::sparql::QueryResultSyntax;
///
/// assert_eq!(QueryResultSyntax::Json.iri(), "http://www.w3.org/ns/formats/SPARQL_Results_JSON")
/// ```
pub fn iri(self) -> &'static str {
match self {
QueryResultSyntax::Xml => "http://www.w3.org/ns/formats/SPARQL_Results_XML",
QueryResultSyntax::Json => "http://www.w3.org/ns/formats/SPARQL_Results_JSON",
}
}
fn media_type(self) -> &'static str {
/// The syntax [IANA media type](https://tools.ietf.org/html/rfc2046).
///
/// ```
/// use oxigraph::sparql::QueryResultSyntax;
///
/// assert_eq!(QueryResultSyntax::Json.media_type(), "application/sparql-results+json")
/// ```
pub fn media_type(self) -> &'static str {
match self {
QueryResultSyntax::Xml => "application/sparql-results+xml",
QueryResultSyntax::Json => "application/sparql-results+json",
}
}
fn file_extension(self) -> &'static str {
/// The syntax [IANA-registered](https://tools.ietf.org/html/rfc2046) file extension.
///
/// ```
/// use oxigraph::sparql::QueryResultSyntax;
///
/// assert_eq!(QueryResultSyntax::Json.file_extension(), "srj")
/// ```
pub fn file_extension(self) -> &'static str {
match self {
QueryResultSyntax::Xml => "srx",
QueryResultSyntax::Json => "srj",
}
}
fn from_mime_type(media_type: &str) -> Option<Self> {
/// Looks for a known syntax from a media type.
///
/// It supports some media type aliases.
/// For example "application/xml" is going to return `QueryResultSyntax::Xml` even if it is not its canonical media type.
///
/// Example:
/// ```
/// use oxigraph::sparql::QueryResultSyntax;
///
/// assert_eq!(QueryResultSyntax::from_media_type("application/sparql-results+json; charset=utf-8"), Some(QueryResultSyntax::Json))
/// ```
pub fn from_media_type(media_type: &str) -> Option<Self> {
if let Some(base_type) = media_type.split(';').next() {
match base_type {
"application/sparql-results+xml" | "application/xml" | "text/xml" => {
@ -159,6 +191,25 @@ impl FileSyntax for QueryResultSyntax {
}
}
#[allow(deprecated)]
impl FileSyntax for QueryResultSyntax {
fn iri(self) -> &'static str {
self.iri()
}
fn media_type(self) -> &'static str {
self.media_type()
}
fn file_extension(self) -> &'static str {
self.file_extension()
}
fn from_mime_type(media_type: &str) -> Option<Self> {
Self::from_media_type(media_type)
}
}
/// An iterator over query result solutions
///
/// ```

@ -2,7 +2,7 @@ use crate::model::*;
use crate::store_utils::*;
use oxigraph::model::*;
use oxigraph::sparql::QueryOptions;
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, MemoryStore};
use oxigraph::{DatasetSyntax, GraphSyntax, MemoryStore};
use pyo3::basic::CompareOp;
use pyo3::exceptions::{NotImplementedError, ValueError};
use pyo3::prelude::*;
@ -81,7 +81,7 @@ impl PyMemoryStore {
Some(base_iri)
};
if let Some(graph_syntax) = GraphSyntax::from_mime_type(mime_type) {
if let Some(graph_syntax) = GraphSyntax::from_media_type(mime_type) {
self.inner
.load_graph(
Cursor::new(data),
@ -90,7 +90,7 @@ impl PyMemoryStore {
base_iri,
)
.map_err(|e| ParseError::py_err(e.to_string()))
} else if let Some(dataset_syntax) = DatasetSyntax::from_mime_type(mime_type) {
} else if let Some(dataset_syntax) = DatasetSyntax::from_media_type(mime_type) {
if to_graph_name.is_some() {
return Err(ValueError::py_err(
"The target graph name parameter is not available for dataset formats",

@ -2,7 +2,7 @@ use crate::model::*;
use crate::store_utils::*;
use oxigraph::model::*;
use oxigraph::sparql::QueryOptions;
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, SledStore};
use oxigraph::{DatasetSyntax, GraphSyntax, SledStore};
use pyo3::exceptions::{IOError, ValueError};
use pyo3::prelude::*;
use pyo3::types::PyTuple;
@ -87,7 +87,7 @@ impl PySledStore {
Some(base_iri)
};
if let Some(graph_syntax) = GraphSyntax::from_mime_type(mime_type) {
if let Some(graph_syntax) = GraphSyntax::from_media_type(mime_type) {
self.inner
.load_graph(
Cursor::new(data),
@ -96,7 +96,7 @@ impl PySledStore {
base_iri,
)
.map_err(|e| ParseError::py_err(e.to_string()))
} else if let Some(dataset_syntax) = DatasetSyntax::from_mime_type(mime_type) {
} else if let Some(dataset_syntax) = DatasetSyntax::from_media_type(mime_type) {
if to_graph_name.is_some() {
return Err(ValueError::py_err(
"The target graph name parameter is not available for dataset formats",

@ -18,7 +18,7 @@ use async_std::task::{block_on, spawn, spawn_blocking};
use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode};
use oxigraph::model::GraphName;
use oxigraph::sparql::{Query, QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, RocksDbStore};
use oxigraph::{DatasetSyntax, GraphSyntax, RocksDbStore};
use std::str::FromStr;
use url::form_urlencoded;
@ -60,7 +60,7 @@ async fn handle_request(request: Request, store: RocksDbStore) -> Result<Respons
}
("/", Method::Post) => {
if let Some(content_type) = request.content_type() {
match if let Some(format) = GraphSyntax::from_mime_type(content_type.essence()) {
match if let Some(format) = GraphSyntax::from_media_type(content_type.essence()) {
spawn_blocking(move || {
store.load_graph(
SyncAsyncBufReader::from(request),
@ -69,7 +69,8 @@ async fn handle_request(request: Request, store: RocksDbStore) -> Result<Respons
None,
)
})
} else if let Some(format) = DatasetSyntax::from_mime_type(content_type.essence()) {
} else if let Some(format) = DatasetSyntax::from_media_type(content_type.essence())
{
spawn_blocking(move || {
store.load_dataset(SyncAsyncBufReader::from(request), format, None)
})
@ -178,6 +179,7 @@ async fn evaluate_sparql_query(
GraphSyntax::Turtle.media_type(),
GraphSyntax::RdfXml.media_type(),
],
GraphSyntax::from_media_type,
)?;
let mut body = Vec::default();
results.write_graph(&mut body, format)?;
@ -191,6 +193,7 @@ async fn evaluate_sparql_query(
QueryResultSyntax::Xml.media_type(),
QueryResultSyntax::Json.media_type(),
],
QueryResultSyntax::from_media_type,
)?;
let mut body = Vec::default();
results.write(&mut body, format)?;
@ -236,7 +239,11 @@ async fn http_server<
Ok(())
}
fn content_negotiation<F: FileSyntax>(request: Request, supported: &[&str]) -> Result<F> {
fn content_negotiation<F>(
request: Request,
supported: &[&str],
parse: impl Fn(&str) -> Option<F>,
) -> Result<F> {
let header = request
.header(headers::ACCEPT)
.map(|h| h.last().as_str().trim())
@ -272,7 +279,7 @@ fn content_negotiation<F: FileSyntax>(request: Request, supported: &[&str]) -> R
}
}
F::from_mime_type(result.essence())
parse(result.essence())
.ok_or_else(|| Error::from_str(StatusCode::InternalServerError, "Unknown mime type"))
}

@ -17,7 +17,7 @@ use async_std::prelude::*;
use async_std::task::{spawn, spawn_blocking};
use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode};
use oxigraph::sparql::{Query, QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::{FileSyntax, GraphSyntax, RocksDbStore};
use oxigraph::{GraphSyntax, RocksDbStore};
use std::str::FromStr;
use std::time::Duration;
use url::form_urlencoded;
@ -188,6 +188,7 @@ async fn evaluate_sparql_query(
GraphSyntax::Turtle.media_type(),
GraphSyntax::RdfXml.media_type(),
],
GraphSyntax::from_media_type,
)?;
let mut body = Vec::default();
results.write_graph(&mut body, format)?;
@ -201,6 +202,7 @@ async fn evaluate_sparql_query(
QueryResultSyntax::Xml.media_type(),
QueryResultSyntax::Json.media_type(),
],
QueryResultSyntax::from_media_type,
)?;
let mut body = Vec::default();
results.write(&mut body, format)?;
@ -246,7 +248,11 @@ async fn http_server<
Ok(())
}
fn content_negotiation<F: FileSyntax>(request: Request, supported: &[&str]) -> Result<F> {
fn content_negotiation<F>(
request: Request,
supported: &[&str],
parse: impl Fn(&str) -> Option<F>,
) -> Result<F> {
let header = request
.header(headers::ACCEPT)
.map(|h| h.last().as_str().trim())
@ -282,6 +288,6 @@ fn content_negotiation<F: FileSyntax>(request: Request, supported: &[&str]) -> R
}
}
F::from_mime_type(result.essence())
parse(result.essence())
.ok_or_else(|| Error::from_str(StatusCode::InternalServerError, "Unknown mime type"))
}

Loading…
Cancel
Save