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

A mapping of prefix atoms to IRI namespaces.

The empty prefix is represented as the `:""` atom.

This module implements the `Enumerable` protocol.

# `coercible_namespace`

```elixir
@type coercible_namespace() :: RDF.Vocabulary.Namespace.t() | String.t() | RDF.IRI.t()
```

# `coercible_prefix`

```elixir
@type coercible_prefix() :: atom() | String.t()
```

# `conflict_resolver`

```elixir
@type conflict_resolver() ::
  (coercible_prefix(), coercible_namespace(), coercible_namespace() -&gt;
     coercible_namespace())
  | :ignore
  | :overwrite
```

# `namespace`

```elixir
@type namespace() :: RDF.IRI.t()
```

# `prefix`

```elixir
@type prefix() :: atom()
```

# `prefix_map`

```elixir
@type prefix_map() :: %{required(prefix()) =&gt; namespace()}
```

# `t`

```elixir
@type t() :: %RDF.PrefixMap{map: prefix_map()}
```

# `add`

```elixir
@spec add(t(), coercible_prefix(), coercible_namespace()) ::
  {:ok, t()} | {:error, String.t()}
```

Adds a prefix mapping to `prefix_map`.

Unless a mapping of `prefix` to a different namespace already exists,
an `:ok` tuple is returned, otherwise an `:error` tuple.

# `add!`

```elixir
@spec add!(t(), coercible_prefix(), coercible_namespace()) :: t()
```

Adds a prefix mapping to the given `RDF.PrefixMap` and raises an exception in error cases.

# `delete`

```elixir
@spec delete(t(), coercible_prefix()) :: t()
```

Deletes the prefix mapping for `prefix` from `prefix_map`.

If no mapping for `prefix` exists, `prefix_map` is returned unchanged.

# `drop`

```elixir
@spec drop(t(), [coercible_prefix()]) :: t()
```

Drops the given `prefixes` from `prefix_map`.

If `prefixes` contains prefixes that are not in `prefix_map`, they're simply ignored.

# `empty?`

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

Returns if the given `prefix_map` is empty.

# `has_prefix?`

```elixir
@spec has_prefix?(t(), coercible_prefix()) :: boolean()
```

Returns whether the given prefix exists in the given `RDF.PrefixMap`.

# `limit`

```elixir
@spec limit(t(), [prefix()]) :: t()
```

Returns a new prefix map limited to the given prefixes.

## Examples

    iex> RDF.PrefixMap.new(ex1: "http://example.com/ns1", ex2: "http://example.com/ns2")
    ...> |> RDF.PrefixMap.limit([:ex1])
    RDF.PrefixMap.new(ex1: "http://example.com/ns1")
    iex> RDF.PrefixMap.new(ex: "http://example.com/")
    ...> |> RDF.PrefixMap.limit([:foo])
    RDF.PrefixMap.new()

# `merge`

```elixir
@spec merge(t(), t() | map() | keyword()) ::
  {:ok, t()} | {:error, [atom() | String.t()]}
```

Merges two `RDF.PrefixMap`s.

The second prefix map can also be given as any structure which can converted
to a `RDF.PrefixMap` via `new/1`.

If the prefix maps can be merged without conflicts, that is there are no
prefixes mapped to different namespaces an `:ok` tuple is returned.
Otherwise, an `:error` tuple with the list of prefixes with conflicting
namespaces is returned.

See also `merge/3` which allows you to resolve conflicts with a function.

# `merge`

```elixir
@spec merge(t(), t() | map() | keyword(), conflict_resolver() | nil) ::
  {:ok, t()} | {:error, [atom() | String.t()]}
```

Merges two `RDF.PrefixMap`s, resolving conflicts through the given `conflict_resolver` function.

The second prefix map can also be given as any structure which can converted
to a `RDF.PrefixMap` via `new/1`.

The given function will be invoked when there are conflicting mappings of
prefixes to different namespaces; its arguments are `prefix`, `namespace1`
(the namespace for the prefix in the first prefix map),
and `namespace2` (the namespace for the prefix in the second prefix map).
The value returned by the `conflict_resolver` function is used as the namespace
for the prefix in the resulting prefix map.
Non-`RDF.IRI` values will be tried to be converted to `RDF.IRI`s via
`RDF.IRI.new` implicitly.

The most common conflict resolution strategies on can be chosen directly with
the following atoms:

- `:ignore`: keep the original namespace from `prefix_map1`
- `:overwrite`: use the other namespace from `prefix_map2`

If a conflict can't be resolved, the provided function can return `nil`.
This will result in an overall return of an `:error` tuple with the list of
prefixes for which the conflict couldn't be resolved.

If everything could be merged, an `:ok` tuple is returned.

# `merge!`

```elixir
@spec merge!(t(), t() | map() | keyword(), conflict_resolver() | nil) :: t()
```

Merges two `RDF.PrefixMap`s and raises an exception in error cases.

See `merge/2` and `merge/3` for more information on merging prefix maps.

# `namespace`

```elixir
@spec namespace(t(), coercible_prefix()) :: namespace() | nil
```

Returns the namespace for the given `prefix` in `prefix_map`.

Returns `nil`, when the given `prefix` is not present in `prefix_map`.

# `namespaces`

```elixir
@spec namespaces(t()) :: [coercible_namespace()]
```

Returns all namespaces from the given `RDF.PrefixMap`.

# `new`

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

Creates an empty `RDF.PrefixMap`.

# `new`

```elixir
@spec new(t() | map() | keyword()) :: t()
```

Creates a new `RDF.PrefixMap` with initial mappings.

The initial prefix mappings can be passed as keyword lists or maps.
The keys for the prefixes can be given as atoms or strings and will be normalized to atoms.
The namespaces can be given as `RDF.IRI`s or strings and will be normalized to `RDF.IRI`s.

# `prefix`

```elixir
@spec prefix(t(), coercible_namespace()) :: coercible_prefix() | nil
```

Returns the prefix for the given `namespace` in `prefix_map`.

Returns `nil`, when the given `namespace` is not present in `prefix_map`.

# `prefixed_name`

```elixir
@spec prefixed_name(t(), RDF.IRI.t() | String.t()) :: String.t() | nil
```

Converts an IRI into a prefixed name.

Returns `nil` when no prefix for the namespace of `iri` is defined in `prefix_map`.

## Examples

    iex> RDF.PrefixMap.new(ex: "http://example.com/")
    ...> |> RDF.PrefixMap.prefixed_name(~I<http://example.com/Foo>)
    "ex:Foo"
    iex> RDF.PrefixMap.new(ex: "http://example.com/")
    ...> |> RDF.PrefixMap.prefixed_name("http://example.com/Foo")
    "ex:Foo"

# `prefixed_name_to_iri`

```elixir
@spec prefixed_name_to_iri(t(), String.t()) :: RDF.IRI.t() | nil
```

Converts a prefixed name into an IRI.

Returns `nil` when the prefix in `prefixed_name` is not defined in `prefix_map`.

## Examples

    iex> RDF.PrefixMap.new(ex: "http://example.com/")
    ...> |> RDF.PrefixMap.prefixed_name_to_iri("ex:Foo")
    ~I<http://example.com/Foo>

# `prefixes`

```elixir
@spec prefixes(t()) :: [coercible_prefix()]
```

Returns all prefixes from the given `RDF.PrefixMap`.

# `put`

```elixir
@spec put(t(), coercible_prefix(), coercible_namespace()) :: t()
```

Adds a prefix mapping to `prefix_map` overwriting an existing mapping.

# `to_header`

```elixir
@spec to_header(t(), :sparql | :turtle, keyword()) :: String.t() | iolist()
```

Converts the given `prefix_map` to a Turtle or SPARQL header string.

The `style` argument can be either `:sparql` or `:turtle`.

## Options

- `:indent`: allows to specify an integer by how many spaces the header
  should be indented (default: `0`)
- `:iodata`: return the header as an IO list

## Examples

    iex> RDF.PrefixMap.new(
    ...>   foo: "http://example.com/foo",
    ...>   bar: "http://example.com/bar"
    ...> ) |> RDF.PrefixMap.to_header(:sparql)
    """
    PREFIX bar: <http://example.com/bar>
    PREFIX foo: <http://example.com/foo>
    """

    iex> RDF.PrefixMap.new(
    ...>   foo: "http://example.com/foo",
    ...>   bar: "http://example.com/bar"
    ...> ) |> RDF.PrefixMap.to_header(:turtle)
    """
    @prefix bar: <http://example.com/bar> .
    @prefix foo: <http://example.com/foo> .
    """

    iex> RDF.PrefixMap.new() |> RDF.PrefixMap.to_header(:sparql)
    ""

# `to_list`

```elixir
@spec to_list(t()) :: [{prefix(), namespace()}]
```

Converts prefix map to a list.

Each prefix-namespace pair in the prefix map is converted to a two-element tuple
`{prefix, namespace_iri}` in the resulting list.

## Examples

    iex> RDF.PrefixMap.new(ex: "http://example.com/") |> RDF.PrefixMap.to_list()
    [ex: ~I<http://example.com/>]

# `to_sorted_list`

```elixir
@spec to_sorted_list(t() | map() | keyword()) :: [{prefix(), namespace()}]
```

Converts prefix map to a list sorted by prefix.

Each prefix-namespace pair in the prefix map is converted to a two-element tuple
`{prefix, namespace_iri}` in the resulting list.

## Examples

    iex> RDF.PrefixMap.new(
    ...>   foo: "http://example.com/foo",
    ...>   bar: "http://example.com/bar")
    ...> |> RDF.PrefixMap.to_sorted_list()
    [bar: ~I<http://example.com/bar>, foo: ~I<http://example.com/foo>]

    iex> RDF.PrefixMap.new(
    ...>   a: "http://example.com/foo",
    ...>   "": "http://example.com/bar")
    ...> |> RDF.PrefixMap.to_sorted_list()
    ["": ~I<http://example.com/bar>, a: ~I<http://example.com/foo>]

# `to_sparql`

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

Converts the given `prefix_map` to a SPARQL header string.

## Examples

    iex> RDF.PrefixMap.new(
    ...>   foo: "http://example.com/foo",
    ...>   bar: "http://example.com/bar"
    ...> ) |> RDF.PrefixMap.to_sparql()
    """
    PREFIX bar: <http://example.com/bar>
    PREFIX foo: <http://example.com/foo>
    """

# `to_turtle`

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

Converts the given `prefix_map` to a Turtle header string.

## Examples

    iex> RDF.PrefixMap.new(
    ...>   foo: "http://example.com/foo",
    ...>   bar: "http://example.com/bar"
    ...> ) |> RDF.PrefixMap.to_turtle()
    """
    @prefix bar: <http://example.com/bar> .
    @prefix foo: <http://example.com/foo> .
    """

---

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