core: add documentation for RDF.Literal and RDF.Datatypes

This commit is contained in:
Marcel Otto 2017-06-10 00:18:39 +02:00
parent f5593aeef7
commit 2a8cf08c8e
10 changed files with 104 additions and 22 deletions

View file

@ -1,16 +1,41 @@
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.Datatype.NS.XSD
@doc """
The URI of the datatype.
"""
@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
@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 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 """
Converts a value into a proper native value.
@ -26,11 +51,10 @@ defmodule RDF.Datatype do
"""
@callback convert(any, keyword) :: any
@callback valid?(RDF.Literal.t) :: boolean
@callback build_literal_by_value(binary, keyword) :: RDF.Literal.t
@callback build_literal_by_lexical(binary, keyword) :: RDF.Literal.t
@callback build_literal(any, binary, keyword) :: RDF.Literal.t
@doc """
Determines if the value of a `RDF.Literal` is a member of lexical value space of its datatype.
"""
@callback valid?(literal :: RDF.Literal.t) :: boolean
# 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,
}
@doc """
The mapping of URIs of datatypes to their `RDF.Datatype`.
"""
def mapping, do: @mapping
@doc """
The URIs of all datatypes with a `RDF.Datatype` defined.
"""
def ids, do: Map.keys(@mapping)
@doc """
All defined `RDF.Datatype` modules.
"""
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(id), do: @mapping[id]

View file

@ -1,4 +1,8 @@
defmodule RDF.Boolean do
@moduledoc """
`RDF.Datatype` for XSD boolean.
"""
use RDF.Datatype, id: RDF.Datatype.NS.XSD.boolean

View file

@ -1,4 +1,8 @@
defmodule RDF.Date do
@moduledoc """
`RDF.Datatype` for 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/

View file

@ -1,4 +1,8 @@
defmodule RDF.DateTime do
@moduledoc """
`RDF.Datatype` for XSD dateTime.
"""
use RDF.Datatype, id: RDF.Datatype.NS.XSD.dateTime

View file

@ -1,4 +1,8 @@
defmodule RDF.Double do
@moduledoc """
`RDF.Datatype` for XSD double.
"""
use RDF.Datatype, id: RDF.Datatype.NS.XSD.double

View file

@ -1,4 +1,8 @@
defmodule RDF.Integer do
@moduledoc """
`RDF.Datatype` for XSD integer.
"""
use RDF.Datatype, id: RDF.Datatype.NS.XSD.integer

View file

@ -1,4 +1,8 @@
defmodule RDF.LangString do
@moduledoc """
`RDF.Datatype` for RDF langString.
"""
use RDF.Datatype, id: RDF.langString

View file

@ -1,4 +1,8 @@
defmodule RDF.String do
@moduledoc """
`RDF.Datatype` for XSD string.
"""
use RDF.Datatype, id: RDF.Datatype.NS.XSD.string

View file

@ -1,4 +1,8 @@
defmodule RDF.Time do
@moduledoc """
`RDF.Datatype` for 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/

View file

@ -2,6 +2,7 @@ defmodule RDF.Literal do
@moduledoc """
RDF literals are leaf nodes of a RDF graph containing raw data, like strings and numbers.
"""
defstruct [:value, :uncanonical_lexical, :datatype, :language]
@type t :: module
@ -21,16 +22,16 @@ defmodule RDF.Literal do
The following mapping of Elixir types to XSD datatypes is applied:
| Elixir type | XSD datatype |
| :-------------- | :----------- |
| `string` | `string` |
| `boolean` | `boolean` |
| `integer` | `integer` |
| `float` | `double` |
| `Time` | `time` |
| `Date` | `date` |
| `DateTime` | `dateTime` |
| `NaiveDateTime` | `dateTime` |
| Elixir datatype | XSD datatype |
| :-------------- | :------------- |
| `string` | `xsd:string` |
| `boolean` | `xsd:boolean` |
| `integer` | `xsd:integer` |
| `float` | `xsd:double` |
| `Time` | `xsd:time` |
| `Date` | `xsd:date` |
| `DateTime` | `xsd:dateTime` |
| `NaiveDateTime` | `xsd:dateTime` |
# Examples
@ -85,6 +86,9 @@ defmodule RDF.Literal do
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
case RDF.Datatype.get(id) do
nil -> to_string(value)
@ -94,7 +98,9 @@ defmodule RDF.Literal do
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{datatype: id} = literal) do
case RDF.Datatype.get(id) do
@ -104,10 +110,16 @@ defmodule RDF.Literal do
end
@doc """
Returns if the given literal is in its canonical lexical representation.
"""
def canonical?(%RDF.Literal{uncanonical_lexical: nil}), do: true
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
case RDF.Datatype.get(id) do
nil -> true
@ -117,7 +129,7 @@ defmodule RDF.Literal do
@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.
@ -128,7 +140,7 @@ defmodule RDF.Literal do
@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>
"""
@ -137,7 +149,7 @@ defmodule RDF.Literal do
@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`.
@ -149,7 +161,7 @@ defmodule RDF.Literal do
@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.
For all practical purposes, this includes `xsd:string` literals too.