-module(metamon@config). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/metamon/config.gleam"). -export([default_config/0, with_runs/2, with_seed/2, with_max_size/2, with_shrink_limit/2, with_max_edges/2, with_regression_file/2, with_diff_enabled/2, with_output_format/2, with_runs_or_panic/2, with_max_size_or_panic/2, with_shrink_limit_or_panic/2, with_max_edges_or_panic/2, with_regression_file_or_panic/2, runs/1, seed/1, max_size/1, shrink_limit/1, max_edges/1, regression_file/1, diff_enabled/1, output_format/1]). -export_type([config_error/0, output_format/0, config/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Configuration for property and metamorphic runs. Construct via\n" " `default_config()` and the `with_*` builders. All builders that\n" " validate input return a `Result` so misconfiguration is visible\n" " at the type level (no silent fallback).\n" ). -type config_error() :: {non_positive, binary(), integer()} | {invalid_path, binary(), binary()}. -type output_format() :: text | json. -opaque config() :: {config, integer(), metamon@generator@seed:seed(), integer(), integer(), integer(), gleam@option:option(binary()), boolean(), output_format()}. -file("src/metamon/config.gleam", 42). ?DOC(" Default configuration: 100 runs, max_size 99, random seed, etc.\n"). -spec default_config() -> config(). default_config() -> {config, 100, metamon@generator@seed:random_seed(), 99, 1024, 16, none, true, text}. -file("src/metamon/config.gleam", 56). ?DOC(" Override the number of successful runs.\n"). -spec with_runs(config(), integer()) -> {ok, config()} | {error, config_error()}. with_runs(C, N) -> case N =< 0 of true -> {error, {non_positive, <<"runs"/utf8>>, N}}; false -> {ok, {config, N, erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), erlang:element(9, C)}} end. -file("src/metamon/config.gleam", 64). ?DOC(" Override the seed.\n"). -spec with_seed(config(), metamon@generator@seed:seed()) -> config(). with_seed(C, S) -> {config, erlang:element(2, C), S, erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), erlang:element(9, C)}. -file("src/metamon/config.gleam", 69). ?DOC(" Override `max_size`.\n"). -spec with_max_size(config(), integer()) -> {ok, config()} | {error, config_error()}. with_max_size(C, N) -> case N =< 0 of true -> {error, {non_positive, <<"max_size"/utf8>>, N}}; false -> {ok, {config, erlang:element(2, C), erlang:element(3, C), N, erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), erlang:element(9, C)}} end. -file("src/metamon/config.gleam", 77). ?DOC(" Override the shrink limit.\n"). -spec with_shrink_limit(config(), integer()) -> {ok, config()} | {error, config_error()}. with_shrink_limit(C, N) -> case N =< 0 of true -> {error, {non_positive, <<"shrink_limit"/utf8>>, N}}; false -> {ok, {config, erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), N, erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), erlang:element(9, C)}} end. -file("src/metamon/config.gleam", 85). ?DOC(" Override the cap on the size of edge cartesian products.\n"). -spec with_max_edges(config(), integer()) -> {ok, config()} | {error, config_error()}. with_max_edges(C, N) -> case N =< 0 of true -> {error, {non_positive, <<"max_edges"/utf8>>, N}}; false -> {ok, {config, erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), N, erlang:element(7, C), erlang:element(8, C), erlang:element(9, C)}} end. -file("src/metamon/config.gleam", 108). ?DOC( " Set a regression file path. The file is created on first failure\n" " and read on every subsequent run.\n" "\n" " File format (TOML-flavoured, schema version 1) is documented in\n" " `metamon/internal/regression`. A version mismatch (a file written\n" " by a newer metamon) makes the runner skip replay rather than\n" " silently mis-parse forward-incompatible content; legacy v0 files\n" " without a `schema_version` header are still accepted.\n" "\n" " Concurrency: each call to `record_regression_for` reads the file,\n" " appends one entry, and writes back. Concurrent test workers\n" " pointed at the same path can lose entries; use distinct paths per\n" " worker if you run properties in parallel within the same process\n" " (especially on the JavaScript target — on the BEAM, gleeunit's\n" " per-test process isolation already serialises file access for the\n" " tests themselves, but custom drivers should still split paths).\n" ). -spec with_regression_file(config(), binary()) -> {ok, config()} | {error, config_error()}. with_regression_file(C, Path) -> case Path of <<""/utf8>> -> {error, {invalid_path, Path, <<"empty"/utf8>>}}; _ -> {ok, {config, erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), {some, Path}, erlang:element(8, C), erlang:element(9, C)}} end. -file("src/metamon/config.gleam", 119). ?DOC(" Enable or disable structural diff in failure output.\n"). -spec with_diff_enabled(config(), boolean()) -> config(). with_diff_enabled(C, Enabled) -> {config, erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), Enabled, erlang:element(9, C)}. -file("src/metamon/config.gleam", 126). ?DOC( " Choose the failure-report output format. `Text` is the default;\n" " `Json` produces a single-line JSON object suitable for piping\n" " into CI dashboards or LLM-driven analysis.\n" ). -spec with_output_format(config(), output_format()) -> config(). with_output_format(C, Fmt) -> {config, erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), Fmt}. -file("src/metamon/config.gleam", 181). -spec describe_error(config_error()) -> binary(). describe_error(E) -> case E of {non_positive, Field, Value} -> <<<<< 0 (got "/utf8>>/binary, (erlang:integer_to_binary(Value))/binary>>/binary, ")"/utf8>>; {invalid_path, Path, Reason} -> <<<<<<<<"regression_file path is "/utf8, Reason/binary>>/binary, " (got \""/utf8>>/binary, Path/binary>>/binary, "\")"/utf8>> end. -file("src/metamon/config.gleam", 174). -spec unwrap_or_panic(binary(), {ok, config()} | {error, config_error()}) -> config(). unwrap_or_panic(Name, Result) -> case Result of {ok, C} -> C; {error, E} -> erlang:error(#{gleam_error => panic, message => (<<<<<<"metamon."/utf8, Name/binary>>/binary, ": "/utf8>>/binary, (describe_error(E))/binary>>), file => <>, module => <<"metamon/config"/utf8>>, function => <<"unwrap_or_panic"/utf8>>, line => 177}) end. -file("src/metamon/config.gleam", 143). ?DOC( " Like `with_runs`, but panics with a structured message on invalid\n" " input. Intended for hard-coded test configuration where the bound\n" " is statically known.\n" ). -spec with_runs_or_panic(config(), integer()) -> config(). with_runs_or_panic(C, N) -> unwrap_or_panic(<<"with_runs_or_panic"/utf8>>, with_runs(C, N)). -file("src/metamon/config.gleam", 149). ?DOC( " Like `with_max_size`, but panics with a structured message on\n" " invalid input. Intended for hard-coded test configuration.\n" ). -spec with_max_size_or_panic(config(), integer()) -> config(). with_max_size_or_panic(C, N) -> unwrap_or_panic(<<"with_max_size_or_panic"/utf8>>, with_max_size(C, N)). -file("src/metamon/config.gleam", 155). ?DOC( " Like `with_shrink_limit`, but panics with a structured message on\n" " invalid input. Intended for hard-coded test configuration.\n" ). -spec with_shrink_limit_or_panic(config(), integer()) -> config(). with_shrink_limit_or_panic(C, N) -> unwrap_or_panic( <<"with_shrink_limit_or_panic"/utf8>>, with_shrink_limit(C, N) ). -file("src/metamon/config.gleam", 161). ?DOC( " Like `with_max_edges`, but panics with a structured message on\n" " invalid input. Intended for hard-coded test configuration.\n" ). -spec with_max_edges_or_panic(config(), integer()) -> config(). with_max_edges_or_panic(C, N) -> unwrap_or_panic(<<"with_max_edges_or_panic"/utf8>>, with_max_edges(C, N)). -file("src/metamon/config.gleam", 167). ?DOC( " Like `with_regression_file`, but panics with a structured message\n" " on invalid input. Intended for hard-coded test configuration.\n" ). -spec with_regression_file_or_panic(config(), binary()) -> config(). with_regression_file_or_panic(C, Path) -> unwrap_or_panic( <<"with_regression_file_or_panic"/utf8>>, with_regression_file(C, Path) ). -file("src/metamon/config.gleam", 193). ?DOC(" The number of successful runs the runner targets per property.\n"). -spec runs(config()) -> integer(). runs(C) -> erlang:element(2, C). -file("src/metamon/config.gleam", 199). ?DOC( " The seed used to drive the deterministic PRNG. `with_seed`\n" " pins this to a fixed value for reproducibility.\n" ). -spec seed(config()) -> metamon@generator@seed:seed(). seed(C) -> erlang:element(3, C). -file("src/metamon/config.gleam", 205). ?DOC( " Upper bound on the `Range` size parameter; controls the\n" " complexity ramp from the first run to the last.\n" ). -spec max_size(config()) -> integer(). max_size(C) -> erlang:element(4, C). -file("src/metamon/config.gleam", 211). ?DOC( " Maximum number of shrink steps the runner attempts on a single\n" " failure before giving up.\n" ). -spec shrink_limit(config()) -> integer(). shrink_limit(C) -> erlang:element(5, C). -file("src/metamon/config.gleam", 217). ?DOC( " Cap on the size of the cartesian-product edge sets that\n" " combinators like `tuple2` / `map2` build up.\n" ). -spec max_edges(config()) -> integer(). max_edges(C) -> erlang:element(6, C). -file("src/metamon/config.gleam", 222). ?DOC(" Path to the regression file; `None` disables the feature.\n"). -spec regression_file(config()) -> gleam@option:option(binary()). regression_file(C) -> erlang:element(7, C). -file("src/metamon/config.gleam", 227). ?DOC(" Whether structural diff is shown in failure output.\n"). -spec diff_enabled(config()) -> boolean(). diff_enabled(C) -> erlang:element(8, C). -file("src/metamon/config.gleam", 232). ?DOC(" Selected failure-report format (`Text` or `Json`).\n"). -spec output_format(config()) -> output_format(). output_format(C) -> erlang:element(9, C).