Coelho.Document.Error (coelho v0.3.1)

Copy Markdown View Source

A single validation failure, located in the document tree.

The :path is a list of segments from the root: string keys for map fields, integers for positions inside content.

Summary

Functions

Takes an error apart, for an application that has to word it itself.

Renders an error as content[0].attrs.href: message.

Renders a path as content[0].attrs.href, or "" for the document itself.

An English sentence, for when there is no translator in the building.

Types

description()

@type description() :: %{
  position: [pos_integer()],
  scope: :document | :node | :mark | :attribute,
  attribute: String.t() | nil,
  mark: pos_integer() | nil,
  location: String.t(),
  message: String.t()
}

segment()

@type segment() :: String.t() | non_neg_integer()

t()

@type t() :: %Coelho.Document.Error{message: String.t(), path: [segment()]}

Functions

describe(error)

@spec describe(t()) :: description()

Takes an error apart, for an application that has to word it itself.

format/1 says content[0].attrs.href: scheme "javascript" is not allowed, which is right for a log and wrong for the person who pasted the link. Wording it for them needs their language and their vocabulary — a market gardener reads "the link in the first paragraph", not a path — and neither of those is Coelho's to choose. This gives the pieces:

%{
  position: [1],
  scope: :attribute,
  attribute: "href",
  mark: 1,
  location: "content[0].marks[0].attrs.href",
  message: ~s(scheme "javascript" is not allowed)
}

:position counts from 1, down the content tree, so [2, 1] is the first child of the second block. :scope is :document, :node, :mark or :attribute. :mark is which mark on the node, from 1, when the failure is on one; :attribute is the attribute's name.

What is deliberately absent is the type — which node, which mark. An error path carries positions, not names, and inventing them here would mean re-walking the document this error came from without being handed it. An application that needs the type has the document.

case Coelho.Document.Error.describe(error) do
  %{scope: :attribute, attribute: "href", position: [n]} ->
    gettext("The link in paragraph %{n} is not allowed.", n: n)

  %{position: [n | _]} ->
    gettext("Paragraph %{n} could not be saved.", n: n)
end

format(error)

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

Renders an error as content[0].attrs.href: message.

format_path(path)

@spec format_path([segment()]) :: String.t()

Renders a path as content[0].attrs.href, or "" for the document itself.

humanize(error)

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

An English sentence, for when there is no translator in the building.

A default and not an answer: it reads block 2, "href": scheme "javascript" is not allowed, which is a great deal better than a dotted path and still not what you would write for your own readers. Use describe/1 for that.