Visualize.Data.Schema (Visualize v0.3.0)

Copy Markdown View Source

A feed's schema: what each of its fields means (spec/08 §10.1, D-136).

A schema maps a field — named as the feed's rows name it, an atom or a string — to a description: its type, and as much of unit, quantity, label, order, status, polarity, target, continuity and window as the feed knows. It says what the numbers are, whoever draws them, and never how they are drawn: a description has no colour key, since colour is the theme's to choose from the meaning (#533). A :time field holds instants; a feed whose clock is a number describes it :number and window: true, the field its windows are over (D-154).

A schema is identified by its version, a content hash (spec/08 §10.2): the same schema has the same version on every node and under every release, and any change of content is a new version. A Visualize.Data.Delivery names the version its rows were produced under; Visualize.Data.Schema.Cache holds schemas by {feed, version}.

Examples

iex> {:ok, schema} =
...>   Visualize.Data.Schema.new(%{
...>     t: %{type: :time},
...>     latency: %{type: :number, unit: "s", quantity: :duration, label: "Request time"},
...>     state: %{type: :category, order: ["ok", "warn", "fail"],
...>              status: %{"ok" => :good, "warn" => :warning, "fail" => :bad}}
...>   })
iex> Visualize.Data.Schema.fetch(schema, "latency", :unit)
{:ok, "s"}
iex> String.length(Visualize.Data.Schema.version(schema))
64
iex> Visualize.Data.Schema.new(%{state: %{type: :category, colors: %{"ok" => "#0a0"}}})
{:error, [{[:state, :colors], {:colour_key, :colors}}]}

Summary

Types

What one field means (spec/08 §10.1).

A fault of new/1: the path from the schema to the value, and why.

A field name, as the feed's rows spell it.

t()

Functions

The ten description keys, :type first (spec/08 §10.1).

A field's description, by either spelling of its name (spec/08 §6.2).

One attribute of a field's description; :error when the field or the attribute is absent.

One fault of new/1 as a line a person reads.

The schema of a map of field descriptions, or every fault of it by path (spec/08 §10.1).

The schema of a map of field descriptions, or ArgumentError naming every fault.

The schema's version: the SHA-256 of its canonical encoding as 64 lowercase hex digits (spec/08 §10.2), computed once by new/1.

Types

description()

@type description() :: %{
  :type => :time | :number | :category | :text,
  optional(:unit) => String.t(),
  optional(:quantity) => atom(),
  optional(:label) => String.t(),
  optional(:order) => [String.t() | atom() | number(), ...],
  optional(:status) => %{required(term()) => atom()},
  optional(:polarity) => :higher_is_better | :lower_is_better | :neutral,
  optional(:target) => number(),
  optional(:continuity) => number(),
  optional(:window) => boolean()
}

What one field means (spec/08 §10.1).

error()

@type error() :: {[name() | atom() | non_neg_integer() | term()], term()}

A fault of new/1: the path from the schema to the value, and why.

name()

@type name() :: atom() | String.t()

A field name, as the feed's rows spell it.

t()

@type t() :: %Visualize.Data.Schema{
  fields: %{required(name()) => description()},
  version: String.t()
}

Functions

attributes()

@spec attributes() :: [atom(), ...]

The ten description keys, :type first (spec/08 §10.1).

fetch(schema, name)

@spec fetch(t(), name()) :: {:ok, description()} | :error

A field's description, by either spelling of its name (spec/08 §6.2).

iex> schema = Visualize.Data.Schema.new!(%{"v" => %{type: :number}})
iex> Visualize.Data.Schema.fetch(schema, :v)
{:ok, %{type: :number}}
iex> Visualize.Data.Schema.fetch(schema, :w)
:error

fetch(schema, name, key)

@spec fetch(t(), name(), atom()) :: {:ok, term()} | :error

One attribute of a field's description; :error when the field or the attribute is absent.

format_error(arg)

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

One fault of new/1 as a line a person reads.

iex> Visualize.Data.Schema.format_error({[:latency, :unit], {:invalid_for, :category}})
"latency.unit: is not a key a :category field takes"

new(fields)

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

The schema of a map of field descriptions, or every fault of it by path (spec/08 §10.1).

iex> Visualize.Data.Schema.new(%{v: %{type: :category, unit: "s"}})
{:error, [{[:v, :unit], {:invalid_for, :category}}]}

new!(fields)

@spec new!(term()) :: t()

The schema of a map of field descriptions, or ArgumentError naming every fault.

version(schema)

@spec version(t()) :: String.t()

The schema's version: the SHA-256 of its canonical encoding as 64 lowercase hex digits (spec/08 §10.2), computed once by new/1.