A declarative family catalog for a family-rich mutator's configuration.
A plugin that emits many mutation kinds under one mutator module usually exposes a
families: option so users can narrow the catalog. This module generates that option's
selection-and-validation machinery from one declaration, so every such plugin parses the
same grammar — the one Mutare's own {:builtins, except: […]} uses — and fails loudly in
the same shapes:
defmodule MyPlugin.Config do
use Mutare.Mutator.Families,
plugin: "MyPlugin",
all: ~w(comparison connective null_predicate string_literal)a,
opt_in: ~w(string_literal)a
enduse options:
:all(required) — every family the mutator can emit, ordered; duplicates rejected.:opt_in(default[]) — the subset excluded from the default set; each must be in:all.:plugin(default the using module's name) — the name error messages blame, e.g."Mutare.Ecto".
The declaration generates, all overridable:
all_families/0— the:alllist;default_families/0—all -- opt_in, the set used whenfamilies:is unset;parse_families!/1— a configuredfamilies:value (:default,:all, an explicit list, or{:all | :default, except: […]}) to the enabledMapSet, raisingArgumentErroron an unknown family or a malformedexcept:;family_enabled?/2— whether a family is in a parsed set, or in the set a raw keyword list'sfamilies:value parses to;@type family— the union of the declared family atoms.
Only selection and validation are generated. What each family means — notes, variant
labels, delivery — stays the plugin's, typically alongside this use in its config module.
Parse once per run by calling parse_families!/1 from the mutator's
Mutare.Mutator.init/1 and reading the result back from context.config; then apply
the selection once, in Mutare.Mutator.finalize/2 — Mutare runs it on every produced
mutation, on both delivery paths, so producers stay pure and no delivery site can forget
the filter.
Summary
Types
The catalog a use Mutare.Mutator.Families declaration compiles to — the value the
generated functions close over and the runtime faces (parse!/2, enabled?/3) take.
Functions
Whether family is enabled — the runtime behind the generated family_enabled?/2.
A MapSet is an already-parsed selection; a keyword list is raw options, whose
families: value (default :default) is parsed first.
Parses a families: value against catalog — the runtime behind the generated
parse_families!/1, kept here so the grammar and its error messages are owned once.
Types
The catalog a use Mutare.Mutator.Families declaration compiles to — the value the
generated functions close over and the runtime faces (parse!/2, enabled?/3) take.
Functions
Whether family is enabled — the runtime behind the generated family_enabled?/2.
A MapSet is an already-parsed selection; a keyword list is raw options, whose
families: value (default :default) is parsed first.
Parses a families: value against catalog — the runtime behind the generated
parse_families!/1, kept here so the grammar and its error messages are owned once.