Add RDF.Literal.new!/2

This commit is contained in:
Marcel Otto 2018-03-14 11:46:11 +01:00
parent e80488d601
commit 733ee44749
4 changed files with 61 additions and 9 deletions

View file

@ -7,10 +7,16 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
## Unreleased
### Added
- `RDF.Literal.new!/2` which fails when creating an invalid literal
### Changed
- `Literal.new/2` can create `rdf:langString` literals without failing, they are
simply invalid
- `RDF.Literal.new/2` can create `rdf:langString` literals without failing, they
are simply invalid; if you want to fail without a language tag use the new
`RDF.Literal.new!/2` function
[Compare v0.4.0...HEAD](https://github.com/marcelotto/rdf-ex/compare/v0.4.0...HEAD)

View file

@ -349,6 +349,8 @@ iex> RDF.Literal.valid? RDF.Integer.new("foo")
false
```
If you want to prohibit the creation of invalid literals, you can use the `new!` constructor function of `RDF.Datatype` or `RDF.Literal`, which will fail in case of invalid values.
A RDF literal is bound to the lexical form of the initially given value. This lexical representation can be retrieved with the `RDF.Literal.lexical/1` function:
```elixir
@ -706,8 +708,7 @@ Note: The later command requires the `json_ld` package to be defined as a depend
The file read and write functions are also able to infer the format from the file extension of the given filename.
```elixir
"/path/to/some_file.ttl"
|> RDF.read_file!()
RDF.read_file!("/path/to/some_file.ttl")
|> RDF.write_file!("/path/to/some_file.jsonld")
```

View file

@ -48,6 +48,9 @@ defimpl Inspect, for: RDF.BlankNode do
end
defimpl Inspect, for: RDF.Literal do
@xsd_string RDF.Datatype.NS.XSD.string
@rdf_lang_string RDF.langString
def inspect(%RDF.Literal{value: value, language: language}, _opts) when not is_nil(language) do
~s[~L"#{value}"#{language}]
end
@ -57,11 +60,14 @@ defimpl Inspect, for: RDF.Literal do
"%RDF.Literal{value: #{inspect value}, lexical: #{inspect lexical}, datatype: ~I<#{datatype}>}"
end
def inspect(%RDF.Literal{value: value, datatype: datatype}, _opts) do
if datatype == RDF.Datatype.NS.XSD.string do
~s[~L"#{value}"]
else
"%RDF.Literal{value: #{inspect value}, datatype: ~I<#{datatype}>}"
def inspect(%RDF.Literal{value: value, datatype: datatype, language: language}, _opts) do
case datatype do
@xsd_string ->
~s[~L"#{value}"]
@rdf_lang_string ->
"%RDF.Literal{value: #{inspect value}, datatype: ~I<#{datatype}>, language: #{inspect language}}"
_ ->
"%RDF.Literal{value: #{inspect value}, datatype: ~I<#{datatype}>}"
end
end
end

View file

@ -59,6 +59,11 @@ defmodule RDF.Literal do
raise RDF.Literal.InvalidError, "#{inspect value} not convertible to a RDF.Literal"
end
@doc """
Creates a new `RDF.Literal` with the given datatype or language tag.
"""
def new(value, opts)
def new(value, opts) when is_list(opts),
do: new(value, Map.new(opts))
@ -88,6 +93,40 @@ defmodule RDF.Literal do
do: new(value)
@doc """
Creates a new `RDF.Literal`, but fails if it's not valid.
Note: Validation is only possible if an `RDF.Datatype` with an implementation of
`RDF.Datatype.valid?/1` exists.
## Examples
iex> RDF.Literal.new!("3.14", datatype: XSD.double) == RDF.Literal.new("3.14", datatype: XSD.double)
true
iex> RDF.Literal.new!("invalid", datatype: "http://example/unkown_datatype") == RDF.Literal.new("invalid", datatype: "http://example/unkown_datatype")
true
iex> RDF.Literal.new!("foo", datatype: XSD.integer)
** (RDF.Literal.InvalidError) invalid RDF.Literal: %RDF.Literal{value: nil, lexical: "foo", datatype: ~I<http://www.w3.org/2001/XMLSchema#integer>}
iex> RDF.Literal.new!("foo", datatype: RDF.langString)
** (RDF.Literal.InvalidError) invalid RDF.Literal: %RDF.Literal{value: "foo", datatype: ~I<http://www.w3.org/1999/02/22-rdf-syntax-ns#langString>, language: nil}
"""
def new!(value, opts \\ %{}) do
with %RDF.Literal{} = literal <- new(value, opts) do
if valid?(literal) do
literal
else
raise RDF.Literal.InvalidError, "invalid RDF.Literal: #{inspect literal}"
end
else
invalid ->
raise RDF.Literal.InvalidError, "invalid result of RDF.Literal.new: #{inspect invalid}"
end
end
@doc """
Returns the given literal with the canonical lexical representation according to its datatype.
"""