Localize.Message.Validator (Localize v1.0.0)

Copy Markdown View Source

Validates a parsed MF2 message against the data-model rules of TR35 Part 9, "Data Model Errors".

Localize.Message.Parser.parse/1 checks syntax only, so a syntactically valid message can still be semantically invalid — most commonly a .local declaration that reads the variable it declares. Parsing and validation are kept separate so tooling that must accept invalid input, such as a syntax highlighter, can parse without validating; everything that formats or serializes a message runs both:

with {:ok, ast} <- Localize.Message.Parser.parse(message),
     :ok <- Localize.Message.Validator.validate(ast) do
  # syntax errors surface first, then data-model errors
end

Summary

Functions

Validates a parsed MF2 message against the TR35 data-model rules.

Types

error()

@type error() ::
  {:duplicate_declaration, String.t()}
  | {:duplicate_option_name, String.t()}
  | {:duplicate_variant, String.t()}
  | {:missing_selector_annotation, String.t()}
  | {:variant_key_mismatch, String.t()}
  | {:missing_fallback_variant, String.t()}

Functions

validate(ast)

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

Validates a parsed MF2 message against the TR35 data-model rules.

The rules checked are:

  • Duplicate Declaration — a variable declared more than once, including declaring a variable after it was implicitly declared by use in an earlier declaration, and a .local referring to itself.

  • Duplicate Option Name — the same identifier on the left of more than one option in a single expression or markup.

  • Duplicate Variant — the same key list (after NFC normalization of literal keys) on more than one variant.

  • Missing Selector Annotation — a selector that does not resolve, directly or transitively, to a declaration carrying a function.

  • Variant Key Mismatch — a variant whose key count differs from the number of selectors.

  • Missing Fallback Variant — a matcher with no variant whose keys are all *.

Arguments

Returns

  • :ok if the message satisfies every data-model rule.

  • {:error, {reason, detail}} for the first violation found, where detail names the offending variable, option, or key list.

Examples

iex> {:ok, ast} = Localize.Message.Parser.parse(".input {$n :number}\n.match $n\n* {{ok}}")
iex> Localize.Message.Validator.validate(ast)
:ok

iex> {:ok, ast} = Localize.Message.Parser.parse(".local $n = {$n :number}\n.match $n\n* {{no}}")
iex> Localize.Message.Validator.validate(ast)
{:error, {:duplicate_declaration, "n"}}