RDF.JSON (RDF.ex v2.1.0)

View Source

RDF.Literal.Datatype for rdf:JSON.

As specified in RDF 1.2, this datatype allows JSON content as literal values. The lexical forms must conform to RFC 7493 (I-JSON).

See: https://www.w3.org/TR/rdf12-concepts/#section-json

Note

Most functions in this module require OTP 25 or later, since JSON canonicalization (JCS) relies on it.

Summary

Functions

Returns a JCS canonicalized version of a JSON literal.

Determines if the lexical form of a JSON literal is in the canonical form.

Returns the canonical lexical form of a RDF.Literal of this datatype.

Casts a datatype literal of one type into a datatype literal of another type.

Checks if the given literal has this datatype.

Checks if two datatype literals are equal in terms of the values of their value space.

Returns the lexical value of a JSON literal.

Like new/2 but raises an ArgumentError when the value is invalid.

Returns a prettified version of a JSON literal.

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

Determines if a JSON literal is valid with respect to RFC 7493 (I-JSON).

Returns the value of a JSON literal.

Types

lexical()

@type lexical() :: String.t()

t()

@type t() :: %RDF.JSON{lexical: lexical()}

value()

@type value() :: String.t() | number() | boolean() | map() | list() | nil

Functions

canonical(json)

@spec canonical(RDF.Literal.t() | t()) :: RDF.Literal.t()

Returns a JCS canonicalized version of a JSON literal.

When the given literal is invalid, it is returned unchanged.

canonical?(json)

@spec canonical?(RDF.Literal.t() | t()) :: boolean() | nil

Determines if the lexical form of a JSON literal is in the canonical form.

canonical_lexical(literal)

Returns the canonical lexical form of a RDF.Literal of this datatype.

cast(literal_or_value)

Casts a datatype literal of one type into a datatype literal of another type.

Returns nil when the given arguments are not castable into this datatype or when the given argument is an invalid literal.

Implementations define the casting for a given value with the RDF.Literal.Datatype.do_cast/1 callback.

compare(left, right)

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

datatype?(arg1)

Checks if the given literal has this datatype.

equal_value?(left, right)

Checks if two datatype literals are equal in terms of the values of their value space.

Non-RDF.Literals are tried to be coerced via RDF.Literal.coerce/1 before comparison.

Returns nil when the given arguments are not comparable as literals of this datatype.

Invalid literals are only considered equal in this relation when both have the exact same datatype and the same attributes (lexical form, language etc.).

Implementations can customize this equivalence relation via the RDF.Literal.Datatype.do_equal_value_different_datatypes?/2 and RDF.Literal.Datatype.do_equal_value_different_datatypes?/2 callbacks.

lexical(json)

@spec lexical(RDF.Literal.t() | t()) :: String.t()

Returns the lexical value of a JSON literal.

new(value_or_lexical, opts \\ [])

@spec new(
  t() | lexical() | value(),
  keyword()
) :: RDF.Literal.t()

Creates a new RDF.JSON literal.

When given a string it is interpreted as a JSON encoding by default, unless the as_value option is set to true.

Options

  • :as_value - when true, strings are encoded as JSON strings instead of being interpreted as JSON

  • :jason_encode - when true, uses Jason for encoding (instead of JCS), which enables:

  • :pretty - when true, values are encoded in a more readable format (not canonical!)

  • :canonicalize - when true, the value is canonicalized according to JCS; cannot be combined with the :pretty option

  • :jason_encode - when true, uses Jason.Encoder instead of JCS encoding

Examples

iex> RDF.JSON.new(%{foo: 42})

iex> RDF.JSON.new(~s({"foo": 42}))

iex> RDF.JSON.new("not JSON") |> RDF.JSON.valid?()
false

iex> RDF.JSON.new("null") |> RDF.JSON.value()
nil

iex> RDF.JSON.new("null", as_value: true)  |> RDF.JSON.value()
"null"

iex> RDF.JSON.new(%{a: 1}, pretty: true)

# assuming we have a Jason.Encoder protocol implementation of our CustomJSON struct
iex> RDF.JSON.new(%CustomJSON{value: 42}, jason_encode: true, escape: :html_safe)

new!(value_or_lexical, opts \\ [])

@spec new!(
  lexical() | value(),
  keyword()
) :: RDF.Literal.t()

Like new/2 but raises an ArgumentError when the value is invalid.

Examples

iex> RDF.JSON.new!(%{foo: 1})
RDF.JSON.new(%{foo: 1})

iex> RDF.JSON.new!("not JSON")
** (ArgumentError) "not JSON" is not a valid RDF.JSON

prettified(json)

@spec prettified(RDF.Literal.t() | t()) :: RDF.Literal.t()

Returns a prettified version of a JSON literal.

When the given literal is invalid, it is returned unchanged.

update(literal, fun, opts \\ [])

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

valid?(json)

@spec valid?(RDF.Literal.t() | t()) :: boolean() | nil

Determines if a JSON literal is valid with respect to RFC 7493 (I-JSON).

value(literal, opts \\ [])

@spec value(
  RDF.Literal.t() | t(),
  keyword()
) :: value() | :invalid

Returns the value of a JSON literal.

When the given literal is invalid, :invalid is returned.

Options

All options are passed to Jason.decode/2.

Examples

iex> RDF.JSON.new(~s({"foo": 1})) |> RDF.JSON.value()
%{"foo" => 1}

iex> RDF.JSON.new(~s({"foo": 1})) |> RDF.JSON.value(keys: :atoms)
%{foo: 1}