core: add documentation for RDF.Literal and RDF.Datatypes
This commit is contained in:
parent
f5593aeef7
commit
2a8cf08c8e
10 changed files with 104 additions and 22 deletions
|
@ -1,16 +1,41 @@
|
||||||
defmodule RDF.Datatype do
|
defmodule RDF.Datatype do
|
||||||
|
@moduledoc """
|
||||||
|
A behaviour for natively supported literal datatypes.
|
||||||
|
|
||||||
|
A `RDF.Datatype` implements the foundational functions for the lexical form,
|
||||||
|
the validation, conversion and canonicalization of typed `RDF.Literal`s.
|
||||||
|
"""
|
||||||
|
|
||||||
alias RDF.Literal
|
alias RDF.Literal
|
||||||
alias RDF.Datatype.NS.XSD
|
alias RDF.Datatype.NS.XSD
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The URI of the datatype.
|
||||||
|
"""
|
||||||
@callback id :: URI.t
|
@callback id :: URI.t
|
||||||
|
|
||||||
@callback lexical(RDF.Literal.t) :: any
|
@doc """
|
||||||
|
Produces the lexical form of a `RDF.Literal`.
|
||||||
|
"""
|
||||||
|
@callback lexical(literal :: RDF.Literal.t) :: any
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Produces the lexical form of a value.
|
||||||
|
"""
|
||||||
@callback canonical_lexical(any) :: binary
|
@callback canonical_lexical(any) :: binary
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Produces the lexical form of an invalid value of a typed Literal.
|
||||||
|
|
||||||
|
The default implementation of the `_using__` macro just returns `to_string`
|
||||||
|
representation of the value.
|
||||||
|
"""
|
||||||
@callback invalid_lexical(any) :: binary
|
@callback invalid_lexical(any) :: binary
|
||||||
|
|
||||||
@callback canonical(RDF.Literal.t) :: RDF.Literal.t
|
@doc """
|
||||||
|
Produces the canonical form of a `RDF.Literal`.
|
||||||
|
"""
|
||||||
|
@callback canonical(literal :: RDF.Literal.t) :: RDF.Literal.t
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Converts a value into a proper native value.
|
Converts a value into a proper native value.
|
||||||
|
@ -26,11 +51,10 @@ defmodule RDF.Datatype do
|
||||||
"""
|
"""
|
||||||
@callback convert(any, keyword) :: any
|
@callback convert(any, keyword) :: any
|
||||||
|
|
||||||
@callback valid?(RDF.Literal.t) :: boolean
|
@doc """
|
||||||
|
Determines if the value of a `RDF.Literal` is a member of lexical value space of its datatype.
|
||||||
@callback build_literal_by_value(binary, keyword) :: RDF.Literal.t
|
"""
|
||||||
@callback build_literal_by_lexical(binary, keyword) :: RDF.Literal.t
|
@callback valid?(literal :: RDF.Literal.t) :: boolean
|
||||||
@callback build_literal(any, binary, keyword) :: RDF.Literal.t
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: This mapping should be created dynamically and be extendable, to allow user-defined datatypes ...
|
# TODO: This mapping should be created dynamically and be extendable, to allow user-defined datatypes ...
|
||||||
|
@ -45,10 +69,24 @@ defmodule RDF.Datatype do
|
||||||
XSD.dateTime => RDF.DateTime,
|
XSD.dateTime => RDF.DateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The mapping of URIs of datatypes to their `RDF.Datatype`.
|
||||||
|
"""
|
||||||
def mapping, do: @mapping
|
def mapping, do: @mapping
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The URIs of all datatypes with a `RDF.Datatype` defined.
|
||||||
|
"""
|
||||||
def ids, do: Map.keys(@mapping)
|
def ids, do: Map.keys(@mapping)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
All defined `RDF.Datatype` modules.
|
||||||
|
"""
|
||||||
def modules, do: Map.values(@mapping)
|
def modules, do: Map.values(@mapping)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the `RDF.Datatype` for a directly datatype URI or the datatype URI of a `RDF.Literal`.
|
||||||
|
"""
|
||||||
def get(%Literal{datatype: id}), do: get(id)
|
def get(%Literal{datatype: id}), do: get(id)
|
||||||
def get(id), do: @mapping[id]
|
def get(id), do: @mapping[id]
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.Boolean do
|
defmodule RDF.Boolean do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD boolean.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.boolean
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.boolean
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.Date do
|
defmodule RDF.Date do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD date.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.date
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.date
|
||||||
|
|
||||||
@grammar ~r/\A(-?\d{4}-\d{2}-\d{2})((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z/
|
@grammar ~r/\A(-?\d{4}-\d{2}-\d{2})((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z/
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.DateTime do
|
defmodule RDF.DateTime do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD dateTime.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.dateTime
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.dateTime
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.Double do
|
defmodule RDF.Double do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD double.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.double
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.double
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.Integer do
|
defmodule RDF.Integer do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD integer.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.integer
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.integer
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.LangString do
|
defmodule RDF.LangString do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for RDF langString.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.langString
|
use RDF.Datatype, id: RDF.langString
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.String do
|
defmodule RDF.String do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD string.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.string
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.string
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule RDF.Time do
|
defmodule RDF.Time do
|
||||||
|
@moduledoc """
|
||||||
|
`RDF.Datatype` for XSD time.
|
||||||
|
"""
|
||||||
|
|
||||||
use RDF.Datatype, id: RDF.Datatype.NS.XSD.time
|
use RDF.Datatype, id: RDF.Datatype.NS.XSD.time
|
||||||
|
|
||||||
@grammar ~r/\A(\d{2}:\d{2}:\d{2}(?:\.\d+)?)((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z/
|
@grammar ~r/\A(\d{2}:\d{2}:\d{2}(?:\.\d+)?)((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z/
|
||||||
|
|
|
@ -2,6 +2,7 @@ defmodule RDF.Literal do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
RDF literals are leaf nodes of a RDF graph containing raw data, like strings and numbers.
|
RDF literals are leaf nodes of a RDF graph containing raw data, like strings and numbers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct [:value, :uncanonical_lexical, :datatype, :language]
|
defstruct [:value, :uncanonical_lexical, :datatype, :language]
|
||||||
|
|
||||||
@type t :: module
|
@type t :: module
|
||||||
|
@ -21,16 +22,16 @@ defmodule RDF.Literal do
|
||||||
|
|
||||||
The following mapping of Elixir types to XSD datatypes is applied:
|
The following mapping of Elixir types to XSD datatypes is applied:
|
||||||
|
|
||||||
| Elixir type | XSD datatype |
|
| Elixir datatype | XSD datatype |
|
||||||
| :-------------- | :----------- |
|
| :-------------- | :------------- |
|
||||||
| `string` | `string` |
|
| `string` | `xsd:string` |
|
||||||
| `boolean` | `boolean` |
|
| `boolean` | `xsd:boolean` |
|
||||||
| `integer` | `integer` |
|
| `integer` | `xsd:integer` |
|
||||||
| `float` | `double` |
|
| `float` | `xsd:double` |
|
||||||
| `Time` | `time` |
|
| `Time` | `xsd:time` |
|
||||||
| `Date` | `date` |
|
| `Date` | `xsd:date` |
|
||||||
| `DateTime` | `dateTime` |
|
| `DateTime` | `xsd:dateTime` |
|
||||||
| `NaiveDateTime` | `dateTime` |
|
| `NaiveDateTime` | `xsd:dateTime` |
|
||||||
|
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
@ -85,6 +86,9 @@ defmodule RDF.Literal do
|
||||||
do: new(value)
|
do: new(value)
|
||||||
|
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the given literal with the canonical lexical representation according to its datatype.
|
||||||
|
"""
|
||||||
def lexical(%RDF.Literal{value: value, uncanonical_lexical: nil, datatype: id} = literal) do
|
def lexical(%RDF.Literal{value: value, uncanonical_lexical: nil, datatype: id} = literal) do
|
||||||
case RDF.Datatype.get(id) do
|
case RDF.Datatype.get(id) do
|
||||||
nil -> to_string(value)
|
nil -> to_string(value)
|
||||||
|
@ -94,7 +98,9 @@ defmodule RDF.Literal do
|
||||||
|
|
||||||
def lexical(%RDF.Literal{uncanonical_lexical: lexical}), do: lexical
|
def lexical(%RDF.Literal{uncanonical_lexical: lexical}), do: lexical
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the given literal in its canonical lexical representation.
|
||||||
|
"""
|
||||||
def canonical(%RDF.Literal{uncanonical_lexical: nil} = literal), do: literal
|
def canonical(%RDF.Literal{uncanonical_lexical: nil} = literal), do: literal
|
||||||
def canonical(%RDF.Literal{datatype: id} = literal) do
|
def canonical(%RDF.Literal{datatype: id} = literal) do
|
||||||
case RDF.Datatype.get(id) do
|
case RDF.Datatype.get(id) do
|
||||||
|
@ -104,10 +110,16 @@ defmodule RDF.Literal do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns if the given literal is in its canonical lexical representation.
|
||||||
|
"""
|
||||||
def canonical?(%RDF.Literal{uncanonical_lexical: nil}), do: true
|
def canonical?(%RDF.Literal{uncanonical_lexical: nil}), do: true
|
||||||
def canonical?(_), do: false
|
def canonical?(_), do: false
|
||||||
|
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns if the value of the given literal is a valid according to its datatype.
|
||||||
|
"""
|
||||||
def valid?(%RDF.Literal{datatype: id} = literal) do
|
def valid?(%RDF.Literal{datatype: id} = literal) do
|
||||||
case RDF.Datatype.get(id) do
|
case RDF.Datatype.get(id) do
|
||||||
nil -> true
|
nil -> true
|
||||||
|
@ -117,7 +129,7 @@ defmodule RDF.Literal do
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Checks if a literal is a simple literal.
|
Returns if a literal is a simple literal.
|
||||||
|
|
||||||
A simple literal has no datatype or language.
|
A simple literal has no datatype or language.
|
||||||
|
|
||||||
|
@ -128,7 +140,7 @@ defmodule RDF.Literal do
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Checks if a literal is a language-tagged literal.
|
Returns if a literal is a language-tagged literal.
|
||||||
|
|
||||||
see <http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal>
|
see <http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal>
|
||||||
"""
|
"""
|
||||||
|
@ -137,7 +149,7 @@ defmodule RDF.Literal do
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Checks if a literal is a datatyped literal.
|
Returns if a literal is a datatyped literal.
|
||||||
|
|
||||||
For historical reasons, this excludes `xsd:string` and `rdf:langString`.
|
For historical reasons, this excludes `xsd:string` and `rdf:langString`.
|
||||||
|
|
||||||
|
@ -149,7 +161,7 @@ defmodule RDF.Literal do
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Checks if a literal is a plain literal.
|
Returns if a literal is a plain literal.
|
||||||
|
|
||||||
A plain literal may have a language, but may not have a datatype.
|
A plain literal may have a language, but may not have a datatype.
|
||||||
For all practical purposes, this includes `xsd:string` literals too.
|
For all practical purposes, this includes `xsd:string` literals too.
|
||||||
|
|
Loading…
Reference in a new issue