Visualize.Chart.Validator (Visualize v0.2.35)

Copy Markdown View Source

Validates a design map against the schema (spec/14 §10).

validate/1 walks the map with Visualize.Chart.Schema and returns every fault it finds as {path, reason}: the path is the list of keys and indexes from the design to the faulty value, [:marks, 1, :channels, :y], and the reason one of the terms of spec/14 §10.1. References — scales, styles, sources, variables, fields, theme slots — resolve against the design itself, so a design is self-contained or it does not validate. format/1 renders an error as a line a person reads.

Examples

iex> Visualize.Chart.Validator.validate(%{version: 2})
{:error, [{[:frames], :required}]}
iex> Visualize.Chart.Validator.format({[:marks, 1, :channels, :y], :required})
"marks[1].channels.y: is required"

Summary

Types

Keys and list indexes from the design to a value; [] is the design.

Why a value is at fault (spec/14 §10.1).

Functions

One error as path: reason in words; the path in marks[1].channels.y form.

A path as a person reads it — design for the root, else frame.scales.x, marks[0].channels — the one spelling every error, node label and rendered data-node uses (spec/14 §4.7, §18.5).

:ok, or every fault of the design ordered by path.

:ok, or every fault of a fragment read as a kind — per-kind validity (spec/14 §19.8).

Types

error()

@type error() :: {path(), reason()}

path()

@type path() :: [atom() | non_neg_integer()]

Keys and list indexes from the design to a value; [] is the design.

reason()

@type reason() ::
  :required
  | :unknown_key
  | {:type, Visualize.Chart.Schema.type()}
  | {:enum, [atom()]}
  | {:undeclared, :scale | :style | :source | :var | :field | :slot | :paint,
     term()}
  | {:ref_kind, atom(), atom()}
  | {:invalid_for, atom()}
  | {:unsupported_version, term()}
  | {:json, String.t()}
  | {:missing_dependency, :jason}
  | {:unresolved, :var, atom()}
  | {:var_binding, atom()}
  | {:unbound, :source, atom()}
  | {:missing_field, atom()}
  | :conflict
  | :cycle
  | {:cycle, [term()]}
  | {:template, :unterminated | {:hole, String.t()}}
  | :many_kinds
  | :sweep
  | :radius
  | {:zone, String.t(), Visualize.Scale.Time.zone_error()}
  | {:sync, :frame_kind | :x_scale, atom() | nil}
  | {:tiles, :projection, atom()}
  | {:tiles, :attribution | :url | :subdomains}
  | {:outside_domain, atom(),
     number() | {:column, atom(), :number | :text | :time}}
  | {:feeds_domain, atom(), number()}

Why a value is at fault (spec/14 §10.1).

Functions

format(arg)

@spec format(error()) :: String.t()

One error as path: reason in words; the path in marks[1].channels.y form.

format_path(path)

@spec format_path(path()) :: String.t()

A path as a person reads it — design for the root, else frame.scales.x, marks[0].channels — the one spelling every error, node label and rendered data-node uses (spec/14 §4.7, §18.5).

iex> Visualize.Chart.Validator.format_path([:marks, 0, :channels])
"marks[0].channels"
iex> Visualize.Chart.Validator.format_path([])
"design"

validate(map)

@spec validate(term()) :: :ok | {:error, [error(), ...]}

:ok, or every fault of the design ordered by path.

validate(map, kind)

@spec validate(term(), atom()) :: :ok | {:error, [error(), ...]}

:ok, or every fault of a fragment read as a kind — per-kind validity (spec/14 §19.8).

A design is validated whole. A composite must be %{composite: %{uses, vars}} and nothing else, its uses sites. Any other kind is the singular body under its key — %{style: %{…}}, %{frames: %{main: %{…}}} — walked with that kind's schema and no design around it, so a reference to a scale, style, source, variable or field the fragment does not declare is not a fault: a fragment is a piece, and what it refers to is bound where it is composed. A fragment whose one key is not the kind's is refused as {:type, {:node, kind}}.