# `GeoGenius.Providers.ManifestOptions`
[🔗](https://github.com/agoodway/geo_genius/blob/main/lib/geo_genius/providers/manifest_options.ex#L1)

Manifest `options` lookups and payload-field extraction shared by every
provider that reads a code, names, attributes, and external codes out of
a manifest and a staged payload the way `GeoGenius.Providers.GeoJSON` and
`GeoGenius.Providers.CSV` both do.

A provider resolves its own format-specific option keys (`"code_property"`
vs `"code_column"`, and so on -- see the table in `GeoGenius.Provider`'s
moduledoc) and passes the resolved field name or field list in here; this
module never reads the vocabulary a specific format calls its own.

# `area_keys`

```elixir
@spec area_keys(GeoGenius.Manifest.t(), map(), String.t()) ::
  {:ok,
   %{
     code_field: String.t(),
     area_type_key: String.t(),
     authority_key: String.t()
   }}
  | {:error, String.t()}
```

Resolves the three keys every area needs -- its code field, area type, and
authority -- into one map rather than three positional strings.

`code_option_key` is the format-specific option key naming the code field
(`"code_property"` for GeoJSON, `"code_column"` for CSV); `"area_type"` is
the same key for every provider. Returning a map rather than a
`{code_field, area_type_key, authority_key}` tuple means a caller cannot
transpose `area_type_key` and `authority_key` by getting their position
wrong -- both are plain strings, so a transposition here would type-check
and silently mis-file every area in the catalog.

# `attributes`

```elixir
@spec attributes(map(), map(), String.t()) :: map()
```

Takes the manifest-selected attribute fields out of `payload`, keyed by
`option_key` (`"attribute_properties"` for GeoJSON, `"attribute_columns"`
for CSV).

Defaults to `[]` when `option_key` is absent from `options` -- an explicit,
provider-agreed default rather than "every other field", which would
silently widen a catalog's attributes the moment a source added a column
nobody asked to carry forward.

# `authority_key`

```elixir
@spec authority_key(GeoGenius.Manifest.t(), map()) ::
  {:ok, String.t()} | {:error, String.t()}
```

Resolves the authority key from `options["authority"]`, falling back to the
manifest's own authority when the option is absent.

The fallback needs the manifest to name exactly one authority. A manifest
declaring several is describing areas keyed under more than one, which one
option key cannot express, so it must say which under `"authority"` rather
than have the first entry chosen for it -- a silent choice would file every
area of the release under whichever authority happened to be listed first.

# `codes`

```elixir
@spec codes(map(), map(), String.t(), String.t()) :: [
  GeoGenius.Provider.Area.Code.t()
]
```

Builds external codes for one payload from a manifest-configured list of
`%{"type" => code_type, field_key => payload_field}` entries.

`option_key` names the manifest option carrying that list
(`"code_properties"` for GeoJSON, `"code_columns"` for CSV); `field_key`
names the key each entry uses for the payload field
(`"property"` for GeoJSON, `"column"` for CSV). Defaults to `[]`. A row
whose named payload field is blank produces no code for that entry, rather
than a `%Code{}` with an empty `code_value`.

# `names`

```elixir
@spec names(map(), String.t(), [String.t()]) :: [GeoGenius.Provider.Area.Name.t()]
```

Builds the official and alias names for one payload.

`name_field` names the payload key holding the official name; `alias_fields`
names the payload keys holding alias names. Both are already resolved by
the caller from its own format-specific option keys and defaults.

# `require_option`

```elixir
@spec require_option(map(), String.t()) :: {:ok, term()} | {:error, String.t()}
```

Fetches `key` out of `options`, returning an error naming the key rather than raising.

---

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