# `RDF.Literal`
[🔗](https://github.com/rdf-elixir/rdf-ex/blob/v3.0.1/lib/rdf/model/literal.ex#L1)

RDF literals are leaf nodes of an RDF graph containing raw data, like strings, numbers etc.

A literal is a struct consisting of a `literal` field holding either a `RDF.Literal.Datatype` struct
for the respective known datatype of the literal or a `RDF.Literal.Generic` struct if the datatype
is unknown, i.e. has no `RDF.Literal.Datatype` implementation.

# `t`

```elixir
@type t() :: %RDF.Literal{literal: RDF.Literal.Datatype.literal()}
```

# `canonical`

```elixir
@spec canonical(t()) :: t()
```

Transforms the given `literal` into its canonical form.

# `canonical?`

```elixir
@spec canonical?(t()) :: boolean()
```

Returns if the lexical form of the given `literal` has the canonical form.

# `canonical_lexical`

```elixir
@spec canonical_lexical(t()) :: String.t() | nil
```

Returns the canonical lexical of the given `literal`.

# `coerce`

Coerces a new `RDF.Literal` from another value.

The following mapping of Elixir types to XSD datatypes is applied:

| Elixir datatype | XSD datatype   |
| :-------------- | :------------- |
| `string`        | `xsd:string`   |
| `boolean`       | `xsd:boolean`  |
| `integer`       | `xsd:integer`  |
| `float`         | `xsd:double`   |
| `Decimal`       | `xsd:decimal`  |
| `Time`          | `xsd:time`     |
| `Date`          | `xsd:date`     |
| `DateTime`      | `xsd:dateTime` |
| `NaiveDateTime` | `xsd:dateTime` |
| `URI`           | `xsd:AnyURI`   |

When an `RDF.Literal` can not be coerced, `nil` is returned
(as opposed to `new/1` which fails in this case).

## Examples

    iex> RDF.Literal.coerce(42)
    %RDF.Literal{literal: %RDF.XSD.Integer{value: 42}}

# `compare`

```elixir
@spec compare(t(), t()) ::
  RDF.Literal.Datatype.comparison_result() | :indeterminate | nil
```

# `datatype?`

Returns if the given value is a `RDF.Literal` or `RDF.Literal.Datatype` struct.

If you simply want to check for a `RDF.Literal` use pattern matching or `RDF.literal?/1`.
This function is a bit slower than those and most of the time only needed when
implementing `RDF.Literal.Datatype`s where you have to deal with the raw,
i.e. unwrapped `RDF.Literal.Datatype` structs.

# `datatype_id`

```elixir
@spec datatype_id(t()) :: RDF.IRI.t()
```

Returns the IRI of datatype of the given `literal`.

# `equal?`

```elixir
@spec equal?(any(), any()) :: boolean()
```

Checks if two literals are equal.

Two literals are equal if they have the same datatype, value and lexical form.

# `equal_value?`

```elixir
@spec equal_value?(t(), t() | any()) :: boolean()
```

Checks if two literals have equal values.

# `generic?`

```elixir
@spec generic?(t()) :: boolean()
```

Returns if the literal uses the `RDF.Literal.Generic` datatype or on of the dedicated builtin or custom `RDF.Literal.Datatype`s.

# `greater_than?`

```elixir
@spec greater_than?(t(), t()) :: boolean()
```

Checks if the first of two `RDF.Literal`s is greater than the other.

# `has_datatype?`

```elixir
@spec has_datatype?(t()) :: boolean()
```

Returns if a literal is a datatyped literal.

For historical reasons, this excludes `xsd:string` and `rdf:langString`.

see <http://www.w3.org/TR/rdf-concepts/#dfn-typed-literal>

# `has_language?`

```elixir
@spec has_language?(t()) :: boolean()
```

Returns if a literal is a language-tagged literal.

see <http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal>

# `is_a?`

Checks if 'literal' is literal with the given `datatype`.

`datatype` can be one of the following:

- a `RDF.Literal.Datatype` module  which checks if the literal is of this datatype or derived from it
- `RDF.XSD.Numeric` which checks if the literal is one of the numeric XSD datatypes or derived of one of them
- `RDF.XSD.Datatype` which checks if the literal is a XSD datatype or derived of one of them

# `language`

```elixir
@spec language(t()) :: String.t() | nil
```

Returns the language of the given `literal` if present.

# `less_than?`

```elixir
@spec less_than?(t(), t()) :: boolean()
```

Checks if the first of two `RDF.Literal`s is smaller than the other.

# `lexical`

```elixir
@spec lexical(t()) :: String.t()
```

Returns the lexical form of the given `literal`.

# `matches?`

```elixir
@spec matches?(
  t() | String.t(),
  pattern :: t() | String.t(),
  flags :: t() | String.t()
) :: boolean()
```

Matches the lexical form of the given `RDF.Literal` against a XPath and XQuery regular expression pattern with flags.

The regular expression language is defined in _XQuery 1.0 and XPath 2.0 Functions and Operators_.

see <https://www.w3.org/TR/xpath-functions/#func-matches>

# `new`

```elixir
@spec new(t() | any()) :: t() | nil
```

Creates a new `RDF.Literal` of the given value and tries to infer an appropriate XSD datatype.

See `coerce/1` for applied mapping of Elixir types to XSD datatypes.

Note: The `RDF.literal` function is a shortcut to this function.

## Examples

    iex> RDF.Literal.new(42)
    %RDF.Literal{literal: %RDF.XSD.Integer{value: 42}}

# `new`

```elixir
@spec new(
  t() | any(),
  keyword()
) :: t() | nil
```

Creates a new `RDF.Literal` with the given datatype or language tag.

# `new!`

```elixir
@spec new!(
  t() | any(),
  keyword()
) :: t()
```

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("foo")
    %RDF.Literal{literal: %RDF.XSD.String{value: "foo"}}

    iex> RDF.Literal.new!("foo", datatype: RDF.NS.XSD.integer)
    ** (RDF.Literal.InvalidError) invalid RDF.Literal: %RDF.XSD.Integer{value: nil, lexical: "foo"}

    iex> RDF.Literal.new!("foo", datatype: RDF.langString)
    ** (RDF.Literal.InvalidError) invalid RDF.Literal: %RDF.LangString{value: "foo", language: nil}

# `plain?`

```elixir
@spec plain?(t()) :: boolean()
```

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.

see <http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal>

# `simple?`

```elixir
@spec simple?(t()) :: boolean()
```

Returns if a literal is a simple literal.

A simple literal has no datatype or language.

see <http://www.w3.org/TR/sparql11-query/#simple_literal>

# `update`

Updates the value of a `RDF.Literal` without changing everything else.

The optional second argument allows to specify what will be passed to `fun` with the `:as` option,
e.g. with `as: :lexical` the lexical is passed to the function.

## Example

    iex> RDF.XSD.integer(42) |> RDF.Literal.update(fn value -> value + 1 end)
    RDF.XSD.integer(43)
    iex> ~L"foo"de |> RDF.Literal.update(fn _ -> "bar" end)
    ~L"bar"de
    iex> RDF.literal("foo", datatype: "http://example.com/dt") |> RDF.Literal.update(fn _ -> "bar" end)
    RDF.literal("bar", datatype: "http://example.com/dt")
    iex> RDF.XSD.integer(42) |> RDF.XSD.Integer.update(
    ...>   fn value -> value <> "1" end, as: :lexical)
    RDF.XSD.integer(421)

# `valid?`

```elixir
@spec valid?(t() | any()) :: boolean()
```

Returns if the given `literal` is valid with respect to its datatype.

# `value`

```elixir
@spec value(t()) :: any()
```

Returns the value of the given `literal`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
