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 js_sys::{Array, Map};
use oxigraph::model::GraphName; use oxigraph::model::GraphName;
use oxigraph::sparql::{QueryOptions, QueryResult}; use oxigraph::sparql::{QueryOptions, QueryResult};
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, MemoryStore}; use oxigraph::{DatasetSyntax, GraphSyntax, MemoryStore};
use std::convert::TryInto; use std::convert::TryInto;
use std::io::Cursor; use std::io::Cursor;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
@ -157,7 +157,7 @@ impl JsMemoryStore {
None 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 self.store
.load_graph( .load_graph(
Cursor::new(data), Cursor::new(data),
@ -166,7 +166,7 @@ impl JsMemoryStore {
base_iri.as_deref(), base_iri.as_deref(),
) )
.map_err(to_err) .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() { if to_graph_name.is_some() {
return Err(format_err!( return Err(format_err!(
"The target graph name parameter is not available for dataset formats" "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. /// A file serialization format.
/// ///
/// Is implemented by `GraphSyntax` for graph files and `DatasetSyntax` for dataset files. /// 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 { 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; fn iri(self) -> &'static str;
/// Its [IANA media type](https://tools.ietf.org/html/rfc2046). /// Its [IANA media type](https://tools.ietf.org/html/rfc2046).
@ -12,12 +13,6 @@ pub trait FileSyntax: Sized {
fn file_extension(self) -> &'static str; fn file_extension(self) -> &'static str;
/// Looks for a known syntax from a media type. /// 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>; fn from_mime_type(media_type: &str) -> Option<Self>;
} }
@ -32,8 +27,15 @@ pub enum GraphSyntax {
RdfXml, RdfXml,
} }
impl FileSyntax for GraphSyntax { impl GraphSyntax {
fn iri(self) -> &'static str { /// 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 { match self {
GraphSyntax::NTriples => "http://www.w3.org/ns/formats/N-Triples", GraphSyntax::NTriples => "http://www.w3.org/ns/formats/N-Triples",
GraphSyntax::Turtle => "http://www.w3.org/ns/formats/Turtle", 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 { match self {
GraphSyntax::NTriples => "application/n-triples", GraphSyntax::NTriples => "application/n-triples",
GraphSyntax::Turtle => "text/turtle", 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 { match self {
GraphSyntax::NTriples => "nt", GraphSyntax::NTriples => "nt",
GraphSyntax::Turtle => "ttl", GraphSyntax::Turtle => "ttl",
GraphSyntax::RdfXml => "rdf", GraphSyntax::RdfXml => "rdf",
} }
} }
/// Looks for a known syntax from a media type.
fn from_mime_type(media_type: &str) -> Option<Self> { ///
/// 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() { if let Some(base_type) = media_type.split(';').next() {
match base_type { match base_type.trim() {
"application/n-triples" | "text/plain" => Some(GraphSyntax::NTriples), "application/n-triples" | "text/plain" => Some(GraphSyntax::NTriples),
"text/turtle" | "application/turtle" | "application/x-turtle" => { "text/turtle" | "application/turtle" | "application/x-turtle" => {
Some(GraphSyntax::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. /// [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) serialization formats.
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum DatasetSyntax { pub enum DatasetSyntax {
@ -82,31 +127,61 @@ pub enum DatasetSyntax {
TriG, TriG,
} }
impl FileSyntax for DatasetSyntax { impl DatasetSyntax {
fn iri(self) -> &'static str { /// 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 { match self {
DatasetSyntax::NQuads => "http://www.w3.org/ns/formats/N-Quads", DatasetSyntax::NQuads => "http://www.w3.org/ns/formats/N-Quads",
DatasetSyntax::TriG => "http://www.w3.org/ns/formats/TriG", 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 { match self {
DatasetSyntax::NQuads => "application/n-quads", DatasetSyntax::NQuads => "application/n-quads",
DatasetSyntax::TriG => "application/trig", 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 { match self {
DatasetSyntax::NQuads => "nq", DatasetSyntax::NQuads => "nq",
DatasetSyntax::TriG => "trig", DatasetSyntax::TriG => "trig",
} }
} }
/// Looks for a known syntax from a media type.
fn from_mime_type(media_type: &str) -> Option<Self> { ///
/// 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() { if let Some(base_type) = media_type.split(';').next() {
match base_type { match base_type.trim() {
"application/n-quads" | "text/x-nquads" | "text/nquads" => { "application/n-quads" | "text/x-nquads" | "text/nquads" => {
Some(DatasetSyntax::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))))] #![doc(test(attr(deny(warnings))))]
mod error; mod error;
pub mod io;
pub mod model; pub mod model;
pub mod sparql; pub mod sparql;
pub mod store; pub mod store;
mod syntax;
pub use error::Error; pub use error::Error;
pub type Result<T> = ::std::result::Result<T, 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; pub use crate::store::memory::MemoryStore;
#[cfg(feature = "rocksdb")] #[cfg(feature = "rocksdb")]
pub use crate::store::rocksdb::RocksDbStore; pub use crate::store::rocksdb::RocksDbStore;
#[cfg(feature = "sled")] #[cfg(feature = "sled")]
pub use crate::store::sled::SledStore; 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::model::*;
use crate::sparql::json_results::write_json_results; use crate::sparql::json_results::write_json_results;
use crate::sparql::xml_results::{read_xml_results, write_xml_results}; use crate::sparql::xml_results::{read_xml_results, write_xml_results};
use crate::Error; use crate::{Error, Result};
use crate::{FileSyntax, GraphSyntax, Result};
use rand::random; use rand::random;
use rio_api::formatter::TriplesFormatter; use rio_api::formatter::TriplesFormatter;
use rio_turtle::{NTriplesFormatter, TurtleFormatter}; use rio_turtle::{NTriplesFormatter, TurtleFormatter};
@ -120,29 +121,60 @@ pub enum QueryResultSyntax {
Json, Json,
} }
impl FileSyntax for QueryResultSyntax { impl QueryResultSyntax {
fn iri(self) -> &'static str { /// 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 { match self {
QueryResultSyntax::Xml => "http://www.w3.org/ns/formats/SPARQL_Results_XML", QueryResultSyntax::Xml => "http://www.w3.org/ns/formats/SPARQL_Results_XML",
QueryResultSyntax::Json => "http://www.w3.org/ns/formats/SPARQL_Results_JSON", QueryResultSyntax::Json => "http://www.w3.org/ns/formats/SPARQL_Results_JSON",
} }
} }
/// The syntax [IANA media type](https://tools.ietf.org/html/rfc2046).
fn media_type(self) -> &'static str { ///
/// ```
/// use oxigraph::sparql::QueryResultSyntax;
///
/// assert_eq!(QueryResultSyntax::Json.media_type(), "application/sparql-results+json")
/// ```
pub fn media_type(self) -> &'static str {
match self { match self {
QueryResultSyntax::Xml => "application/sparql-results+xml", QueryResultSyntax::Xml => "application/sparql-results+xml",
QueryResultSyntax::Json => "application/sparql-results+json", 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 { match self {
QueryResultSyntax::Xml => "srx", QueryResultSyntax::Xml => "srx",
QueryResultSyntax::Json => "srj", 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() { if let Some(base_type) = media_type.split(';').next() {
match base_type { match base_type {
"application/sparql-results+xml" | "application/xml" | "text/xml" => { "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 /// An iterator over query result solutions
/// ///
/// ``` /// ```

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

@ -2,7 +2,7 @@ use crate::model::*;
use crate::store_utils::*; use crate::store_utils::*;
use oxigraph::model::*; use oxigraph::model::*;
use oxigraph::sparql::QueryOptions; use oxigraph::sparql::QueryOptions;
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, SledStore}; use oxigraph::{DatasetSyntax, GraphSyntax, SledStore};
use pyo3::exceptions::{IOError, ValueError}; use pyo3::exceptions::{IOError, ValueError};
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyTuple; use pyo3::types::PyTuple;
@ -87,7 +87,7 @@ impl PySledStore {
Some(base_iri) 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 self.inner
.load_graph( .load_graph(
Cursor::new(data), Cursor::new(data),
@ -96,7 +96,7 @@ impl PySledStore {
base_iri, base_iri,
) )
.map_err(|e| ParseError::py_err(e.to_string())) .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() { if to_graph_name.is_some() {
return Err(ValueError::py_err( return Err(ValueError::py_err(
"The target graph name parameter is not available for dataset formats", "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 http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode};
use oxigraph::model::GraphName; use oxigraph::model::GraphName;
use oxigraph::sparql::{Query, QueryOptions, QueryResult, QueryResultSyntax}; use oxigraph::sparql::{Query, QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, RocksDbStore}; use oxigraph::{DatasetSyntax, GraphSyntax, RocksDbStore};
use std::str::FromStr; use std::str::FromStr;
use url::form_urlencoded; use url::form_urlencoded;
@ -60,7 +60,7 @@ async fn handle_request(request: Request, store: RocksDbStore) -> Result<Respons
} }
("/", Method::Post) => { ("/", Method::Post) => {
if let Some(content_type) = request.content_type() { 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 || { spawn_blocking(move || {
store.load_graph( store.load_graph(
SyncAsyncBufReader::from(request), SyncAsyncBufReader::from(request),
@ -69,7 +69,8 @@ async fn handle_request(request: Request, store: RocksDbStore) -> Result<Respons
None, 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 || { spawn_blocking(move || {
store.load_dataset(SyncAsyncBufReader::from(request), format, None) store.load_dataset(SyncAsyncBufReader::from(request), format, None)
}) })
@ -178,6 +179,7 @@ async fn evaluate_sparql_query(
GraphSyntax::Turtle.media_type(), GraphSyntax::Turtle.media_type(),
GraphSyntax::RdfXml.media_type(), GraphSyntax::RdfXml.media_type(),
], ],
GraphSyntax::from_media_type,
)?; )?;
let mut body = Vec::default(); let mut body = Vec::default();
results.write_graph(&mut body, format)?; results.write_graph(&mut body, format)?;
@ -191,6 +193,7 @@ async fn evaluate_sparql_query(
QueryResultSyntax::Xml.media_type(), QueryResultSyntax::Xml.media_type(),
QueryResultSyntax::Json.media_type(), QueryResultSyntax::Json.media_type(),
], ],
QueryResultSyntax::from_media_type,
)?; )?;
let mut body = Vec::default(); let mut body = Vec::default();
results.write(&mut body, format)?; results.write(&mut body, format)?;
@ -236,7 +239,11 @@ async fn http_server<
Ok(()) 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 let header = request
.header(headers::ACCEPT) .header(headers::ACCEPT)
.map(|h| h.last().as_str().trim()) .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")) .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 async_std::task::{spawn, spawn_blocking};
use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode}; use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode};
use oxigraph::sparql::{Query, QueryOptions, QueryResult, QueryResultSyntax}; use oxigraph::sparql::{Query, QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::{FileSyntax, GraphSyntax, RocksDbStore}; use oxigraph::{GraphSyntax, RocksDbStore};
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use url::form_urlencoded; use url::form_urlencoded;
@ -188,6 +188,7 @@ async fn evaluate_sparql_query(
GraphSyntax::Turtle.media_type(), GraphSyntax::Turtle.media_type(),
GraphSyntax::RdfXml.media_type(), GraphSyntax::RdfXml.media_type(),
], ],
GraphSyntax::from_media_type,
)?; )?;
let mut body = Vec::default(); let mut body = Vec::default();
results.write_graph(&mut body, format)?; results.write_graph(&mut body, format)?;
@ -201,6 +202,7 @@ async fn evaluate_sparql_query(
QueryResultSyntax::Xml.media_type(), QueryResultSyntax::Xml.media_type(),
QueryResultSyntax::Json.media_type(), QueryResultSyntax::Json.media_type(),
], ],
QueryResultSyntax::from_media_type,
)?; )?;
let mut body = Vec::default(); let mut body = Vec::default();
results.write(&mut body, format)?; results.write(&mut body, format)?;
@ -246,7 +248,11 @@ async fn http_server<
Ok(()) 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 let header = request
.header(headers::ACCEPT) .header(headers::ACCEPT)
.map(|h| h.last().as_str().trim()) .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")) .ok_or_else(|| Error::from_str(StatusCode::InternalServerError, "Unknown mime type"))
} }

Loading…
Cancel
Save