Clean up serialization API, code and documentation
This commit is contained in:
parent
0dc8e383ce
commit
3d28ec9085
12 changed files with 222 additions and 188 deletions
|
@ -181,7 +181,7 @@ defmodule RDF.IRI do
|
|||
Characters additionally allowed in IRI references are treated in the same way that unreserved
|
||||
characters are treated in URI references, per [section 6.5 of RFC3987](http://tools.ietf.org/html/rfc3987#section-6.5)
|
||||
|
||||
If the given is not an absolute IRI `nil` is returned.
|
||||
If the given `base` is not an absolute IRI `nil` is returned.
|
||||
"""
|
||||
@spec absolute(coercible, coercible) :: t | nil
|
||||
def absolute(iri, base) do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule RDF.Serialization.Decoder do
|
||||
@moduledoc """
|
||||
A behaviour for decoders of strings encoded in a specific `RDF.Serialization` format.
|
||||
"""
|
||||
@moduledoc !"""
|
||||
A behaviour for decoders of strings encoded in a specific `RDF.Serialization` format.
|
||||
"""
|
||||
|
||||
alias RDF.{Dataset, Graph}
|
||||
|
||||
|
@ -11,7 +11,7 @@ defmodule RDF.Serialization.Decoder do
|
|||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
"""
|
||||
@callback decode(String.t(), keyword | map) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
@callback decode(String.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
|
||||
@doc """
|
||||
Decodes a serialized `RDF.Graph` or `RDF.Dataset` from the given string.
|
||||
|
@ -21,14 +21,14 @@ defmodule RDF.Serialization.Decoder do
|
|||
Note: The `__using__` macro automatically provides an overridable default
|
||||
implementation based on the non-bang `decode` function.
|
||||
"""
|
||||
@callback decode!(String.t(), keyword | map) :: RDF.Graph.t() | RDF.Dataset.t()
|
||||
@callback decode!(String.t(), keyword) :: RDF.Graph.t() | RDF.Dataset.t()
|
||||
|
||||
defmacro __using__(_) do
|
||||
quote bind_quoted: [], unquote: true do
|
||||
@behaviour unquote(__MODULE__)
|
||||
|
||||
@impl unquote(__MODULE__)
|
||||
@spec decode!(String.t(), keyword | map) :: RDF.Graph.t() | RDF.Dataset.t()
|
||||
@spec decode!(String.t(), keyword) :: RDF.Graph.t() | RDF.Dataset.t()
|
||||
def decode!(content, opts \\ []) do
|
||||
case decode(content, opts) do
|
||||
{:ok, data} -> data
|
||||
|
@ -36,7 +36,7 @@ defmodule RDF.Serialization.Decoder do
|
|||
end
|
||||
end
|
||||
|
||||
defoverridable decode!: 2
|
||||
defoverridable unquote(__MODULE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,29 +1,25 @@
|
|||
defmodule RDF.Serialization.Encoder do
|
||||
@moduledoc """
|
||||
A behaviour for encoders of `RDF.Graph`s or `RDF.Dataset`s in a specific
|
||||
`RDF.Serialization` format.
|
||||
"""
|
||||
|
||||
alias RDF.{Dataset, Graph, Description}
|
||||
@moduledoc !"""
|
||||
A behaviour for encoders of RDF data structures in a specific `RDF.Serialization` format.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Encodes a `RDF.Graph` or `RDF.Dataset`.
|
||||
Serializes a RDF data structure into a string.
|
||||
|
||||
It returns an `{:ok, string}` tuple, with `string` being the serialized
|
||||
`RDF.Graph` or `RDF.Dataset`, or `{:error, reason}` if an error occurs.
|
||||
It should return an `{:ok, string}` tuple, with `string` being the serialized
|
||||
RDF data structure, or `{:error, reason}` if an error occurs.
|
||||
"""
|
||||
@callback encode(Description.t() | Graph.t() | Dataset.t(), keyword | map) ::
|
||||
{:ok, String.t()} | {:error, any}
|
||||
@callback encode(RDF.Data.t(), keyword) :: {:ok, String.t()} | {:error, any}
|
||||
|
||||
@doc """
|
||||
Encodes a `RDF.Graph` or `RDF.Dataset`.
|
||||
Serializes a RDF data structure into a string.
|
||||
|
||||
As opposed to `encode`, it raises an exception if an error occurs.
|
||||
|
||||
Note: The `__using__` macro automatically provides an overridable default
|
||||
implementation based on the non-bang `encode` function.
|
||||
"""
|
||||
@callback encode!(Description.t() | Graph.t() | Dataset.t(), keyword | map) :: String.t()
|
||||
@callback encode!(RDF.Data.t(), keyword) :: String.t()
|
||||
|
||||
defmacro __using__(_) do
|
||||
quote bind_quoted: [], unquote: true do
|
||||
|
@ -39,8 +35,7 @@ defmodule RDF.Serialization.Encoder do
|
|||
end
|
||||
end
|
||||
|
||||
defoverridable encode!: 1
|
||||
defoverridable encode!: 2
|
||||
defoverridable unquote(__MODULE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule RDF.Serialization.Format do
|
|||
@moduledoc """
|
||||
A behaviour for RDF serialization formats.
|
||||
|
||||
A `RDF.Serialization` for a format can be implemented like this
|
||||
A serialization format can be implemented like this
|
||||
|
||||
defmodule SomeFormat do
|
||||
use RDF.Serialization.Format
|
||||
|
@ -28,7 +28,8 @@ defmodule RDF.Serialization.Format do
|
|||
`decoder/0` functions in your `RDF.Serialization.Format` module.
|
||||
"""
|
||||
|
||||
alias RDF.{Dataset, Graph, Description}
|
||||
alias RDF.{Dataset, Graph}
|
||||
alias RDF.Serialization.{Reader, Writer}
|
||||
|
||||
@doc """
|
||||
An IRI of the serialization format.
|
||||
|
@ -73,41 +74,113 @@ defmodule RDF.Serialization.Format do
|
|||
@impl unquote(__MODULE__)
|
||||
def encoder, do: @encoder
|
||||
|
||||
defoverridable decoder: 0, encoder: 0
|
||||
defoverridable unquote(__MODULE__)
|
||||
|
||||
@decoder_doc_ref """
|
||||
See the [module documentation of the decoder](`#{@decoder}`) for the
|
||||
available format-specific options, all of which can be used in this
|
||||
function and will be passed them through to the decoder.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a string.
|
||||
|
||||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
|
||||
#{@decoder_doc_ref}
|
||||
"""
|
||||
@spec read_string(String.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def read_string(content, opts \\ []),
|
||||
do: RDF.Serialization.Reader.read_string(decoder(), content, opts)
|
||||
def read_string(content, opts \\ []), do: Reader.read_string(decoder(), content, opts)
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a string.
|
||||
|
||||
As opposed to `read_string/2`, it raises an exception if an error occurs.
|
||||
|
||||
#{@decoder_doc_ref}
|
||||
"""
|
||||
@spec read_string!(String.t(), keyword) :: Graph.t() | Dataset.t()
|
||||
def read_string!(content, opts \\ []),
|
||||
do: RDF.Serialization.Reader.read_string!(decoder(), content, opts)
|
||||
def read_string!(content, opts \\ []), do: Reader.read_string!(decoder(), content, opts)
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a file.
|
||||
|
||||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
|
||||
#{@decoder_doc_ref}
|
||||
"""
|
||||
@spec read_file(Path.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def read_file(file, opts \\ []),
|
||||
do: RDF.Serialization.Reader.read_file(decoder(), file, opts)
|
||||
def read_file(file, opts \\ []), do: Reader.read_file(decoder(), file, opts)
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a file.
|
||||
|
||||
As opposed to `read_file/2`, it raises an exception if an error occurs.
|
||||
|
||||
#{@decoder_doc_ref}
|
||||
"""
|
||||
@spec read_file!(Path.t(), keyword) :: Graph.t() | Dataset.t()
|
||||
def read_file!(file, opts \\ []),
|
||||
do: RDF.Serialization.Reader.read_file!(decoder(), file, opts)
|
||||
def read_file!(file, opts \\ []), do: Reader.read_file!(decoder(), file, opts)
|
||||
|
||||
@spec write_string(Description.t() | Graph.t() | Dataset.t(), keyword) ::
|
||||
{:ok, String.t()} | {:error, any}
|
||||
def write_string(data, opts \\ []),
|
||||
do: RDF.Serialization.Writer.write_string(encoder(), data, opts)
|
||||
@encoder_doc_ref """
|
||||
See the [module documentation of the encoder](`#{@encoder}`) for the
|
||||
available format-specific options, all of which can be used in this
|
||||
function and will be passed them through to the encoder.
|
||||
"""
|
||||
|
||||
@spec write_string!(Description.t() | Graph.t() | Dataset.t(), keyword) :: String.t()
|
||||
def write_string!(data, opts \\ []),
|
||||
do: RDF.Serialization.Writer.write_string!(encoder(), data, opts)
|
||||
@doc """
|
||||
Serializes a RDF data structure to a string.
|
||||
|
||||
@spec write_file(Description.t() | Graph.t() | Dataset.t(), Path.t(), keyword) ::
|
||||
:ok | {:error, any}
|
||||
def write_file(data, path, opts \\ []),
|
||||
do: RDF.Serialization.Writer.write_file(encoder(), data, path, opts)
|
||||
It returns an `{:ok, string}` tuple, with `string` being the serialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
|
||||
@spec write_file!(Description.t() | Graph.t() | Dataset.t(), Path.t(), keyword) :: :ok
|
||||
def write_file!(data, path, opts \\ []),
|
||||
do: RDF.Serialization.Writer.write_file!(encoder(), data, path, opts)
|
||||
#{@encoder_doc_ref}
|
||||
"""
|
||||
@spec write_string(RDF.Data.t(), keyword) :: {:ok, String.t()} | {:error, any}
|
||||
def write_string(data, opts \\ []), do: Writer.write_string(encoder(), data, opts)
|
||||
|
||||
@doc """
|
||||
Serializes a RDF data structure to a string.
|
||||
|
||||
As opposed to `write_string/2`, it raises an exception if an error occurs.
|
||||
|
||||
#{@encoder_doc_ref}
|
||||
"""
|
||||
@spec write_string!(RDF.Data.t(), keyword) :: String.t()
|
||||
def write_string!(data, opts \\ []), do: Writer.write_string!(encoder(), data, opts)
|
||||
|
||||
@doc """
|
||||
Serializes a RDF data structure to a file.
|
||||
|
||||
It returns `:ok` if successful or `{:error, reason}` if an error occurs.
|
||||
|
||||
## Options
|
||||
|
||||
General serialization-independent options:
|
||||
|
||||
- `:force` - If not set to `true`, an error is raised when the given file
|
||||
already exists (default: `false`)
|
||||
- `:file_mode` - A list with the Elixir `File.open` modes to be used for writing
|
||||
(default: `[:write, :exclusive]`)
|
||||
|
||||
#{@encoder_doc_ref}
|
||||
"""
|
||||
@spec write_file(RDF.Data.t(), Path.t(), keyword) :: :ok | {:error, any}
|
||||
def write_file(data, path, opts \\ []), do: Writer.write_file(encoder(), data, path, opts)
|
||||
|
||||
@doc """
|
||||
Serializes a RDF data structure to a file.
|
||||
|
||||
As opposed to `write_file/3`, it raises an exception if an error occurs.
|
||||
|
||||
See `write_file/3` for the available format-independent options.
|
||||
|
||||
#{@encoder_doc_ref}
|
||||
"""
|
||||
@spec write_file!(RDF.Data.t(), Path.t(), keyword) :: :ok
|
||||
def write_file!(data, path, opts \\ []), do: Writer.write_file!(encoder(), data, path, opts)
|
||||
|
||||
@before_compile unquote(__MODULE__)
|
||||
end
|
||||
|
|
|
@ -1,41 +1,24 @@
|
|||
defmodule RDF.Serialization.Reader do
|
||||
@moduledoc """
|
||||
General functions for reading a `RDF.Graph` or `RDF.Dataset` from a serialization file or encoded-string.
|
||||
@moduledoc !"""
|
||||
General functions for reading a `RDF.Graph` or `RDF.Dataset` from a serialization file, stream or encoded-string.
|
||||
|
||||
You probably won't use these functions directly, but instead use the automatically
|
||||
generated functions with same name on a `RDF.Serialization.Format`, which implicitly
|
||||
use the proper `RDF.Serialization.Decoder` module.
|
||||
"""
|
||||
These functions are not intended for direct use, but instead via the automatically
|
||||
generated functions with the same name on a `RDF.Serialization.Format`, which
|
||||
implicitly use the proper `RDF.Serialization.Decoder` module.
|
||||
"""
|
||||
|
||||
alias RDF.{Dataset, Graph}
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a string.
|
||||
|
||||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
"""
|
||||
@spec read_string(module, String.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def read_string(decoder, content, opts \\ []) do
|
||||
decoder.decode(content, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a string.
|
||||
|
||||
As opposed to `read_string`, it raises an exception if an error occurs.
|
||||
"""
|
||||
@spec read_string!(module, String.t(), keyword) :: Graph.t() | Dataset.t()
|
||||
def read_string!(decoder, content, opts \\ []) do
|
||||
decoder.decode!(content, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a file.
|
||||
|
||||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
"""
|
||||
@spec read_file(module, Path.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def read_file(decoder, file, opts \\ []) do
|
||||
case File.read(file) do
|
||||
|
@ -44,15 +27,9 @@ defmodule RDF.Serialization.Reader do
|
|||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a file.
|
||||
|
||||
As opposed to `read_file`, it raises an exception if an error occurs.
|
||||
"""
|
||||
@spec read_file!(module, Path.t(), keyword) :: Graph.t() | Dataset.t()
|
||||
def read_file!(decoder, file, opts \\ []) do
|
||||
with content = File.read!(file) do
|
||||
read_string!(decoder, content, opts)
|
||||
end
|
||||
content = File.read!(file)
|
||||
read_string!(decoder, content, opts)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
defmodule RDF.Serialization do
|
||||
@moduledoc """
|
||||
General functions for working with RDF serializations.
|
||||
Functions for working with RDF serializations generically.
|
||||
|
||||
Besides some reflection functions regarding available serialization formats,
|
||||
this module includes the full serialization reader and writer API from the
|
||||
serialization format modules.
|
||||
As opposed to calling the reader and writer functions statically on the
|
||||
serialization format module, they can be used more dynamically on this module
|
||||
either by providing the format by name or media type with the `:format` option
|
||||
or in the case of the read and write function on files by relying on detection
|
||||
of the format by file extension.
|
||||
"""
|
||||
|
||||
alias RDF.{Dataset, Graph}
|
||||
|
@ -22,7 +31,7 @@ defmodule RDF.Serialization do
|
|||
## Examples
|
||||
|
||||
iex> RDF.Serialization.formats
|
||||
[RDF.Turtle, JSON.LD, RDF.NTriples, RDF.NQuads]
|
||||
#{inspect(@formats)}
|
||||
|
||||
"""
|
||||
@spec formats :: [format]
|
||||
|
@ -116,13 +125,16 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a string.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format.
|
||||
Deserializes a graph or dataset from a string.
|
||||
|
||||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format.
|
||||
|
||||
Please refer to the documentation of the decoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec read_string(String.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def read_string(content, opts) do
|
||||
|
@ -132,12 +144,15 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a string.
|
||||
Deserializes a graph or dataset from a string.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
As opposed to `read_string/2`, it raises an exception if an error occurs.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format.
|
||||
|
||||
As opposed to `read_string`, it raises an exception if an error occurs.
|
||||
Please refer to the documentation of the decoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec read_string!(String.t(), keyword) :: Graph.t() | Dataset.t()
|
||||
def read_string!(content, opts) do
|
||||
|
@ -149,14 +164,17 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a file.
|
||||
|
||||
The format can be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format. If none of these are
|
||||
given, the format gets inferred from the extension of the given file name.
|
||||
Deserializes a graph or dataset from a file.
|
||||
|
||||
It returns an `{:ok, data}` tuple, with `data` being the deserialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
|
||||
The format can be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format. If none of these are
|
||||
given, the format gets inferred from the extension of the given file name.
|
||||
|
||||
Please refer to the documentation of the decoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec read_file(Path.t(), keyword) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def read_file(file, opts \\ []) do
|
||||
|
@ -166,13 +184,16 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Reads and decodes a serialized graph or dataset from a file.
|
||||
Deserializes a graph or dataset from a file.
|
||||
|
||||
As opposed to `read_file/2`, it raises an exception if an error occurs.
|
||||
|
||||
The format can be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format. If none of these are
|
||||
given, the format gets inferred from the extension of the given file name.
|
||||
|
||||
As opposed to `read_file`, it raises an exception if an error occurs.
|
||||
Please refer to the documentation of the decoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec read_file!(Path.t(), keyword) :: Graph.t() | Dataset.t()
|
||||
def read_file!(file, opts \\ []) do
|
||||
|
@ -184,13 +205,16 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a string.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format.
|
||||
Serializes a RDF data structure to a string.
|
||||
|
||||
It returns an `{:ok, string}` tuple, with `string` being the serialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format.
|
||||
|
||||
Please refer to the documentation of the encoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec write_string(RDF.Data.t(), keyword) :: {:ok, String.t()} | {:error, any}
|
||||
def write_string(data, opts) do
|
||||
|
@ -200,12 +224,15 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a string.
|
||||
Serializes a RDF data structure to a string.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
As opposed to `write_string/2`, it raises an exception if an error occurs.
|
||||
|
||||
The format must be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format.
|
||||
|
||||
As opposed to `write_string`, it raises an exception if an error occurs.
|
||||
Please refer to the documentation of the encoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec write_string!(RDF.Data.t(), keyword) :: String.t()
|
||||
def write_string!(data, opts) do
|
||||
|
@ -217,7 +244,11 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a file.
|
||||
Serializes a RDF data structure to a file.
|
||||
|
||||
It returns `:ok` if successful or `{:error, reason}` if an error occurs.
|
||||
|
||||
## Options
|
||||
|
||||
The format can be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format. If none of these are
|
||||
|
@ -228,9 +259,10 @@ defmodule RDF.Serialization do
|
|||
- `:force` - If not set to `true`, an error is raised when the given file
|
||||
already exists (default: `false`)
|
||||
- `:file_mode` - A list with the Elixir `File.open` modes to be used for writing
|
||||
(default: `[:utf8, :write]`)
|
||||
(default: `[:write, :exclusive]`)
|
||||
|
||||
It returns `:ok` if successful or `{:error, reason}` if an error occurs.
|
||||
Please refer to the documentation of the encoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec write_file(RDF.Data.t(), Path.t(), keyword) :: :ok | {:error, any}
|
||||
def write_file(data, path, opts \\ []) do
|
||||
|
@ -240,15 +272,14 @@ defmodule RDF.Serialization do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a file.
|
||||
Serializes a RDF data structure to a file.
|
||||
|
||||
The format can be specified with the `format` option and a format name or the
|
||||
`media_type` option and the media type of the format. If none of these are
|
||||
given, the format gets inferred from the extension of the given file name.
|
||||
As opposed to `write_file/3`, it raises an exception if an error occurs.
|
||||
|
||||
See `write_file` for a list of other available options.
|
||||
See `write_file/3` for the available format-independent options.
|
||||
|
||||
As opposed to `write_file`, it raises an exception if an error occurs.
|
||||
Please refer to the documentation of the encoder of a RDF serialization format
|
||||
for format-specific options.
|
||||
"""
|
||||
@spec write_file!(RDF.Data.t(), Path.t(), keyword) :: :ok
|
||||
def write_file!(data, path, opts \\ []) do
|
||||
|
|
|
@ -1,75 +1,44 @@
|
|||
defmodule RDF.Serialization.Writer do
|
||||
@moduledoc """
|
||||
General functions for writing the statements of a `RDF.Graph` or `RDF.Dataset` to a serialization file or string.
|
||||
@moduledoc !"""
|
||||
General functions for writing the statements of a RDF data structure to a file, string or stream.
|
||||
|
||||
You probably won't use these functions directly, but instead use the automatically
|
||||
generated functions with same name on a `RDF.Serialization.Format`, which implicitly
|
||||
use the proper `RDF.Serialization.Encoder` module.
|
||||
"""
|
||||
These functions are not intended for direct use, but instead via the automatically
|
||||
generated functions with the same name on a `RDF.Serialization.Format`, which
|
||||
implicitly use the proper `RDF.Serialization.Encoder` module.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a string.
|
||||
@default_file_mode ~w[write exclusive]a
|
||||
|
||||
It returns an `{:ok, string}` tuple, with `string` being the serialized graph or
|
||||
dataset, or `{:error, reason}` if an error occurs.
|
||||
"""
|
||||
@spec write_string(module, RDF.Data.t(), keyword) ::
|
||||
{:ok, String.t()} | {:error, any}
|
||||
@spec write_string(module, RDF.Data.t(), keyword) :: {:ok, String.t()} | {:error, any}
|
||||
def write_string(encoder, data, opts \\ []) do
|
||||
encoder.encode(data, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a string.
|
||||
|
||||
As opposed to `write_string`, it raises an exception if an error occurs.
|
||||
"""
|
||||
@spec write_string!(module, RDF.Data.t(), keyword) :: String.t()
|
||||
def write_string!(encoder, data, opts \\ []) do
|
||||
encoder.encode!(data, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a file.
|
||||
|
||||
General available serialization-independent options:
|
||||
|
||||
- `:force` - If not set to `true`, an error is raised when the given file
|
||||
already exists (default: `false`)
|
||||
- `:file_mode` - A list with the Elixir `File.open` modes to be used for writing
|
||||
(default: `[:write, :exclusive]`)
|
||||
|
||||
It returns `:ok` if successful or `{:error, reason}` if an error occurs.
|
||||
"""
|
||||
@spec write_file(module, RDF.Data.t(), Path.t(), keyword) ::
|
||||
:ok | {:error, any}
|
||||
@spec write_file(module, RDF.Data.t(), Path.t(), keyword) :: :ok | {:error, any}
|
||||
def write_file(encoder, data, path, opts \\ []) do
|
||||
with {:ok, encoded_string} <- write_string(encoder, data, opts) do
|
||||
File.write(path, encoded_string, file_mode(encoder, opts))
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Encodes and writes a graph or dataset to a file.
|
||||
|
||||
See `write_file` for a list of available options.
|
||||
|
||||
As opposed to `write_file`, it raises an exception if an error occurs.
|
||||
"""
|
||||
@spec write_file!(module, RDF.Data.t(), Path.t(), keyword) :: :ok
|
||||
def write_file!(encoder, data, path, opts \\ []) do
|
||||
with encoded_string = write_string!(encoder, data, opts) do
|
||||
File.write!(path, encoded_string, file_mode(encoder, opts))
|
||||
end
|
||||
encoded_string = write_string!(encoder, data, opts)
|
||||
File.write!(path, encoded_string, file_mode(encoder, opts))
|
||||
end
|
||||
|
||||
defp file_mode(_encoder, opts) do
|
||||
with file_mode = Keyword.get(opts, :file_mode, ~w[write exclusive]a) do
|
||||
if Keyword.get(opts, :force) do
|
||||
List.delete(file_mode, :exclusive)
|
||||
else
|
||||
file_mode
|
||||
end
|
||||
file_mode = Keyword.get(opts, :file_mode, @default_file_mode)
|
||||
|
||||
if Keyword.get(opts, :force) do
|
||||
List.delete(file_mode, :exclusive)
|
||||
else
|
||||
file_mode
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,10 +5,10 @@ defmodule RDF.NQuads.Decoder do
|
|||
|
||||
import RDF.Serialization.ParseHelper, only: [error_description: 1]
|
||||
|
||||
alias RDF.{Dataset, Graph}
|
||||
alias RDF.Dataset
|
||||
|
||||
@impl RDF.Serialization.Decoder
|
||||
@spec decode(String.t(), keyword | map) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
@spec decode(String.t(), keyword) :: {:ok, Dataset.t()} | {:error, any}
|
||||
def decode(content, _opts \\ []) do
|
||||
with {:ok, tokens, _} <- tokenize(content),
|
||||
{:ok, ast} <- parse(tokens) do
|
||||
|
@ -24,13 +24,11 @@ defmodule RDF.NQuads.Decoder do
|
|||
end
|
||||
end
|
||||
|
||||
defp tokenize(content), do: content |> to_charlist |> :ntriples_lexer.string()
|
||||
defp tokenize(content), do: content |> to_charlist() |> :ntriples_lexer.string()
|
||||
|
||||
defp parse(tokens), do: tokens |> :nquads_parser.parse()
|
||||
|
||||
defp build_dataset(ast) do
|
||||
Enum.reduce(ast, RDF.Dataset.new(), fn quad, dataset ->
|
||||
RDF.Dataset.add(dataset, quad)
|
||||
end)
|
||||
Enum.reduce(ast, Dataset.new(), &Dataset.add(&2, &1))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,14 +3,14 @@ defmodule RDF.NQuads.Encoder do
|
|||
|
||||
use RDF.Serialization.Encoder
|
||||
|
||||
alias RDF.{Dataset, Graph, Statement}
|
||||
alias RDF.Statement
|
||||
|
||||
@impl RDF.Serialization.Encoder
|
||||
@callback encode(Graph.t() | Dataset.t(), keyword | map) :: {:ok, String.t()} | {:error, any}
|
||||
@callback encode(RDF.Data.t(), keyword) :: {:ok, String.t()} | {:error, any}
|
||||
def encode(data, _opts \\ []) do
|
||||
result =
|
||||
data
|
||||
|> Enum.reduce([], fn statement, result -> [statement(statement) | result] end)
|
||||
|> Enum.reduce([], &[statement(&1) | &2])
|
||||
|> Enum.reverse()
|
||||
|> Enum.join("\n")
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ defmodule RDF.NTriples.Decoder do
|
|||
|
||||
import RDF.Serialization.ParseHelper, only: [error_description: 1]
|
||||
|
||||
alias RDF.{Dataset, Graph}
|
||||
alias RDF.Graph
|
||||
|
||||
@impl RDF.Serialization.Decoder
|
||||
@spec decode(String.t(), keyword | map) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
@spec decode(String.t(), keyword) :: {:ok, Graph.t()} | {:error, any}
|
||||
def decode(content, _opts \\ []) do
|
||||
with {:ok, tokens, _} <- tokenize(content),
|
||||
{:ok, ast} <- parse(tokens) do
|
||||
|
@ -24,13 +24,11 @@ defmodule RDF.NTriples.Decoder do
|
|||
end
|
||||
end
|
||||
|
||||
defp tokenize(content), do: content |> to_charlist |> :ntriples_lexer.string()
|
||||
defp tokenize(content), do: content |> to_charlist() |> :ntriples_lexer.string()
|
||||
|
||||
defp parse(tokens), do: tokens |> :ntriples_parser.parse()
|
||||
|
||||
defp build_graph(ast) do
|
||||
Enum.reduce(ast, RDF.Graph.new(), fn triple, graph ->
|
||||
RDF.Graph.add(graph, triple)
|
||||
end)
|
||||
Enum.reduce(ast, Graph.new(), &Graph.add(&2, &1))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,16 +3,14 @@ defmodule RDF.NTriples.Encoder do
|
|||
|
||||
use RDF.Serialization.Encoder
|
||||
|
||||
alias RDF.{BlankNode, Dataset, Graph, IRI, XSD, Literal, Statement, Triple, LangString}
|
||||
alias RDF.{BlankNode, IRI, XSD, Literal, Statement, Triple, LangString}
|
||||
|
||||
@impl RDF.Serialization.Encoder
|
||||
@callback encode(Graph.t() | Dataset.t(), keyword | map) :: {:ok, String.t()} | {:error, any}
|
||||
@callback encode(RDF.Data.t(), keyword) :: {:ok, String.t()} | {:error, any}
|
||||
def encode(data, _opts \\ []) do
|
||||
result =
|
||||
data
|
||||
|> Enum.reduce([], fn statement, result ->
|
||||
[statement(statement) | result]
|
||||
end)
|
||||
|> Enum.reduce([], &[statement(&1) | &2])
|
||||
|> Enum.reverse()
|
||||
|> Enum.join("\n")
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule RDF.Turtle.Decoder do
|
|||
|
||||
import RDF.Serialization.ParseHelper, only: [error_description: 1]
|
||||
|
||||
alias RDF.{Dataset, Graph, IRI}
|
||||
alias RDF.{Graph, IRI}
|
||||
|
||||
defmodule State do
|
||||
defstruct base_iri: nil, namespaces: %{}, bnode_counter: 0
|
||||
|
@ -24,16 +24,11 @@ defmodule RDF.Turtle.Decoder do
|
|||
end
|
||||
|
||||
@impl RDF.Serialization.Decoder
|
||||
@spec decode(String.t(), keyword | map) :: {:ok, Graph.t() | Dataset.t()} | {:error, any}
|
||||
def decode(content, opts \\ %{})
|
||||
|
||||
def decode(content, opts) when is_list(opts),
|
||||
do: decode(content, Map.new(opts))
|
||||
|
||||
def decode(content, opts) do
|
||||
@spec decode(String.t(), keyword) :: {:ok, Graph.t()} | {:error, any}
|
||||
def decode(content, opts \\ []) do
|
||||
with {:ok, tokens, _} <- tokenize(content),
|
||||
{:ok, ast} <- parse(tokens),
|
||||
base_iri = Map.get(opts, :base, Map.get(opts, :base_iri, RDF.default_base_iri())) do
|
||||
base_iri = Keyword.get(opts, :base, Keyword.get(opts, :base_iri, RDF.default_base_iri())) do
|
||||
build_graph(ast, base_iri && RDF.iri(base_iri))
|
||||
else
|
||||
{:error, {error_line, :turtle_lexer, error_descriptor}, _error_line_again} ->
|
||||
|
|
Loading…
Reference in a new issue