-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", 94). ?DOC( " Set a regression file path. The file is created on first failure\n" " and read on every subsequent run.\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", 105). ?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", 112). ?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", 167). -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", 160). -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 => 163}) end. -file("src/metamon/config.gleam", 129). ?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", 135). ?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", 141). ?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", 147). ?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", 153). ?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", 179). ?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", 185). ?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", 191). ?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", 197). ?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", 203). ?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", 208). ?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", 213). ?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", 218). ?DOC(" Selected failure-report format (`Text` or `Json`).\n"). -spec output_format(config()) -> output_format(). output_format(C) -> erlang:element(9, C).