The reviewed document that describes one release: <manifest_dir>/<collection>/<release>.json.
A manifest is how a new release becomes available -- nothing discovers or
follows a mutable "latest" pointer. load/3 reads and validates the file at
that path; from_map/2 runs the same validation over an already-decoded
document, which is how a manifest stored on release.manifest is rebuilt
without touching the filesystem again. to_map/1 is the inverse of both:
it produces the exact JSON-shaped map a manifest document contains, so
from_map(to_map(m)) round-trips.
Every failure -- a malformed field, an unknown provider, a name that could
escape the manifest directory -- raises or returns GeoGenius.ManifestError
naming the field that was wrong.
Summary
Types
One entry of a manifest's area_types list.
One entry of a manifest's authorities list: who is responsible for the
identifiers a set of areas is keyed under.
Functions
Decodes a manifest document with Jason.
Validates an already-decoded manifest document, skipping the file and
decoding steps load/3 performs.
Loads and validates the manifest for collection/release from the search
path.
Like load/3, but raises GeoGenius.ManifestError instead of returning an error tuple.
Produces the JSON-shaped map a manifest document contains.
Types
@type area_type() :: %{ :key => String.t(), :rank => pos_integer(), optional(:requires_geometry) => boolean() }
One entry of a manifest's area_types list.
One entry of a manifest's authorities list: who is responsible for the
identifiers a set of areas is keyed under.
A collection may draw on more than one -- a US release keyed partly by the Census, partly by the USPS, and partly by its own vendor identifiers names all three -- so this is a list rather than a single value.
authorities is required and must name at least one, unlike area_types,
which a manifest may declare as an empty list: a manifest declaring no area
types registers none, and a release that normalizes an area whose type it
never declared fails. An empty authorities list is a manifest that can
register no area at all: upsert_area resolves an authority with
SELECT ... INTO STRICT and raises :no_data_found deep in normalization.
Rejecting it here is what turns that into an error naming the field, at load.
:authorities is in @enforce_keys for the same reason. Validation covers
the documents load/3 and from_map/2 read; the enforced key covers a
%GeoGenius.Manifest{} built in Elixir, which would otherwise default the
field to nil and reach registration's Enum.each/2 as a
Protocol.UndefinedError rather than an error naming the field.
@type t() :: %GeoGenius.Manifest{ area_types: [area_type()], authorities: [authority()], collection: String.t(), collection_name: String.t() | nil, description: String.t() | nil, options: map(), provider: String.t(), release: String.t(), requires_geometry: boolean(), source_date: Date.t() | nil, sources: [GeoGenius.Manifest.Source.t()] }
Functions
@spec decode(String.t(), Path.t() | nil) :: {:ok, map()} | {:error, GeoGenius.ManifestError.t()}
Decodes a manifest document with Jason.
path is carried onto any GeoGenius.ManifestError this returns, so a
decode failure names the file it came from.
@spec from_map(map(), Path.t() | nil) :: {:ok, t()} | {:error, GeoGenius.ManifestError.t()}
Validates an already-decoded manifest document, skipping the file and
decoding steps load/3 performs.
This is how a manifest stored on release.manifest is rebuilt without
reading it from disk again.
@spec load(String.t(), String.t(), keyword()) :: {:ok, t()} | {:error, GeoGenius.ManifestError.t()}
Loads and validates the manifest for collection/release from the search
path.
Returns {:error, %GeoGenius.ManifestError{}} for a name that cannot be
looked up, a file that is not on the search path, JSON that does not parse,
or a document that fails validation.
Like load/3, but raises GeoGenius.ManifestError instead of returning an error tuple.
Produces the JSON-shaped map a manifest document contains.
from_map(to_map(manifest)) is the identity: this is what makes storing a
manifest on the release row lossless.