Skip to main content

src/molt@value.erl

-module(molt@value).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/molt/value.gleam").
-export([basic_string/1, bool/1, literal_string/1, multiline_basic_string/1, multiline_literal_string/1, string/1, int/1, hex_int/1, octal_int/1, binary_int/1, float/1, infinity/0, signed_infinity/1, nan/0, signed_nan/1, datetime/1, offset_datetime/1, local_datetime/1, local_date/1, local_time/1, table/1, table_from_dict/1, array/1, type_of/1, as_inline_table/1, as_section_table/1, as_array/1, as_array_of_tables/1, as_decimal_int/1, as_hex_int/1, as_octal_int/1, as_binary_int/1, as_basic_string/1, as_multiline_basic_string/1, as_literal_string/1, as_multiline_literal_string/1, to_toml_value/1, inspect/1, invalid_text/1, string_style/1, int_style/1, to_toml/2, is_valid/1, unwrap_string/1, unwrap_string_or/2, unwrap_int/1, unwrap_int_or/2, unwrap_float/1, unwrap_float_or/2, unwrap_bool/1, unwrap_bool_or/2, unwrap_datetime/1, array_get_at/2, array_replace_at/3, array_remove_at/2, array_insert_at/3, array_append/2, array_to_list/1, array_length/1, table_get_key/2, table_has_key/2, table_keys/1, table_set_key/3, table_remove_key/2, table_rename_key/3, table_to_list/1, table_to_dict/1, to_cst/1, from_cst/1, parse_value/1, from_table_entries/1, from_array_of_tables/1]).
-export_type([value/0, sign/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(
    " molt/value: TOML value manipulation\n"
    "\n"
    " This module provides functions for working with TOML data values extracted\n"
    " from the document. All TOML types are supported and there are some\n"
    " convenience functions for manipulating the types.\n"
    "\n"
    " ## `molt/value` Preserves Content, Not Representation\n"
    "\n"
    " `Value` preserves the _content_ of the TOML values, but may change the\n"
    " representation. Extracting a value from the document with `molt.get`,\n"
    " unwrapping it with one of the `unwrap_*` functions, and creating a new\n"
    " value instance to use with `molt.set` is not guaranteed to produce the\n"
    " same representation.\n"
    "\n"
    " - String content is preserved, but not string representation. A multiline\n"
    "   string with line-ending backslashes reads as the joined result:\n"
    "   `\"abc\\↵   xyz\"` becomes `\"abcxyz\"` when accessed with `unwrap_string`.\n"
    "\n"
    " - Integers and Floats lose leading `+` for positive values (`+99` becomes\n"
    "   `99`) and any underscore formatting (`123_456_789`).\n"
    "\n"
    " - Structural values (tables, arrays of tables, inline tables, and arrays)\n"
    "   will lose comments, whitespace, and inline formatting.\n"
    "\n"
    " In most circumstances, `molt/value` manipulation is unnecessary, because\n"
    " the operations provided by `molt/ops` for use with `molt.run` all\n"
    " preserve the document representation.\n"
    "\n"
    " ## Function Categories\n"
    "\n"
    " There are six categories of functions in the `molt/value` interface:\n"
    "\n"
    " - `constructor`: functions that create a Value for the TOML value types\n"
    "   and variants described below, including constructor variants that parse\n"
    "   or classify the provided value. Some constructors perform validation on\n"
    "   the values provided and return `Result(Value, MoltError)` to ensure\n"
    "   that no invalid value is possible.\n"
    "\n"
    " - `coercion`: functions that coerce the representation of types into\n"
    "   alternate, compatible versions. These always return `Result(Value,\n"
    "   MoltError)` since an integer value cannot be represented as a string\n"
    "   without explicit conversion (or the reverse).\n"
    "\n"
    " - `introspection`: functions that help distinguish between TOML value\n"
    "   types and styles, or check the validity of user-constructed `Value`s.\n"
    "\n"
    " - `value`: functions that convert most scalar `Value`s to Gleam values.\n"
    "\n"
    " - `array`: functions that manipulate an array `Value`.\n"
    "\n"
    " - `table`: functions that manipulate a table `Value`.\n"
    "\n"
    " ## TOML Value Types\n"
    "\n"
    " ### [String][toml-string] Values\n"
    "\n"
    " There are four ways to express strings: basic, multi-line basic, literal,\n"
    " and multi-line literal. All strings must contain only Unicode characters.\n"
    "\n"
    " - `basic` strings allow any Unicode character may be used except characters\n"
    "   that must be escaped (`\"`, `\\`, and Unicode characters U+0000 to U+0008,\n"
    "   U+000A to U+001F, and U+007F).\n"
    "\n"
    "   In TOML basic strings are surrounded by single `\"` characters and must\n"
    "   begin and end on a single line.\n"
    "\n"
    " - `multiline basic` strings allow the same characters as `basic` strings,\n"
    "   except that newlines (CRLF or LF) are permitted and retained within the\n"
    "   multiline basic string (except for a newline immediately following the\n"
    "   opening delimiter). Trailing whitespace may be suppressed with the\n"
    "   line-ending `\\`.\n"
    "\n"
    "   In TOML multiline basic strings are surrounded by triple `\"\"\"`\n"
    "   characters, so up to two unescaped quotation marks may be present.\n"
    "\n"
    " - `literal` strings allow any Unicode character _except_ the literal string\n"
    "   delimiter (`'`) and control characters except for tab. Literal strings\n"
    "   must begin and end on a single line. No escapes are performed on literal\n"
    "   strings.\n"
    "\n"
    " - `multiline literal` strings are just like `multiline basic` strings with\n"
    "   `literal` string rules applied. There are no escapes (including line\n"
    "   continuation escapes) and the delimiter is triple `'''`, allowing up to\n"
    "   two single quote marks may be present.\n"
    "\n"
    " ### [Integer][toml-integer] Values\n"
    "\n"
    " Integers are whole numbers. Positive numbers may be prefixed with a plus\n"
    " sign (`+99`). Negative numbers are prefixed with a minus sign (`-99`).\n"
    " Large numbers may have underscores between digits to enhance readability\n"
    " (`123_456_789`). Non-negative integer values may be encoded as hexadecimal\n"
    " (`0x7f`, `0xdead_beef`), octal (`0o755`, `0o0123_4567`), or binary\n"
    " (`0b0110`, `0b0110_1001`).\n"
    "\n"
    " `molt/value` will preserve hex, octal, and binary encoded integers.\n"
    "\n"
    " ### [Float][toml-float] Values\n"
    "\n"
    " A float consists of an integer part (which follows the same rules as\n"
    " decimal integer values) followed by a fractional part and/or an exponent\n"
    " part. If both a fractional part and exponent part are present, the\n"
    " fractional part must precede the exponent part. Fractional parts are\n"
    " separated by a decimal point and must have a digit on either side. As with\n"
    " integers, underscores can separate digits. There are special float values\n"
    " (treated separately by `molt/value`) also permitted:\n"
    "\n"
    " ```toml\n"
    " valid = [+1.0, 3.14_15, -0.01, 5e+22, 1e06, -2E-2, 7_326.626e-34]\n"
    " invalid = [.7, 7., 3.e+20]\n"
    " special = [inf, +inf, -inf, nan, +nan, -nan]\n"
    " ```\n"
    "\n"
    " ### [Boolean][toml-boolean] Values\n"
    "\n"
    " These values are always `true` or `false` and correspond to `True` and\n"
    " `False` Gleam values.\n"
    "\n"
    " ### Date and Time Values\n"
    "\n"
    " TOML supports four date and time value types, which are treated as opaque\n"
    " strings by `molt/value`. TOML date and type value types are not wholly\n"
    " compatible with [`gleam_time`][gleam_time] and are stored internally as the\n"
    " [RFC3339][rfc3339] strings they are parsed from.\n"
    "\n"
    " - [Offset Date-Time][toml-odt]: represents a specific instant with\n"
    "   a timezone offset. Seconds may be omitted in TOML 1.1 (`1979-05-27T07:32Z`\n"
    "   means the same as `1979-05-27T07:32:00Z`).\n"
    " - [Local Date-Time][toml-ldt]: represents a date time without relationship\n"
    "   to a timezone. Seconds may be omitted in TOML 1.1.\n"
    " - [Local Date][toml-ld]: represents a calendar day.\n"
    " - [Local Time][toml-lt]: represents a time of day without any relation to\n"
    "   a specific day or timezone. Seconds may be omitted in TOML 1.1.\n"
    "\n"
    " ### [Array][toml-array] Values\n"
    "\n"
    " Arrays are inline ordered values surrounded by square brackets (`[]`) and\n"
    " are heterogenous containing any `Value`. Newlines are allowed in the\n"
    " document representation, but `molt/value` does not guarantee any\n"
    " particular formatting.\n"
    "\n"
    " ### [Table][toml-table] Values\n"
    "\n"
    " Tables (roughly equivalent to `Dict(String, Value)`) are collections of\n"
    " key/value pairs defined by headers on their own line (`[key]`). Until the\n"
    " next header or end of file are `key = value` pairs. `molt/value` handles\n"
    " tables as the key/value pairs.\n"
    "\n"
    " ### [Inline Table][toml-inline] Values\n"
    "\n"
    " Inline tables provide a more compact syntax for expressing tables, most\n"
    " useful for grouped nested data that can otherwise quickly become verbose.\n"
    " They are proper _values_ are defined within curly braces (`{}`) with commas\n"
    " separating key/value pairs.\n"
    "\n"
    " In TOML 1.1, tables may span multiple lines.\n"
    "\n"
    " ### [Array of Tables][toml-AoT] Values\n"
    "\n"
    " An array of tables (roughly equivalent to `List(Dict(String, Value))`) is\n"
    " expressed as `[[key]]` on its own line with a table body of key/value pairs\n"
    " immediately following.\n"
    "\n"
    " [toml-integer]: https://toml.io/en/v1.1.0#integer\n"
    " [toml-string]: https://toml.io/en/v1.1.0#string\n"
    " [toml-float]: https://toml.io/en/v1.1.0#float\n"
    " [toml-boolean]: https://toml.io/en/v1.1.0#boolean\n"
    " [toml-odt]: https://toml.io/en/v1.1.0#offset-date-time\n"
    " [toml-ldt]: https://toml.io/en/v1.1.0#local-date-time\n"
    " [toml-ld]: https://toml.io/en/v1.1.0#local-date\n"
    " [toml-lt]: https://toml.io/en/v1.1.0#local-time\n"
    " [toml-array]: https://toml.io/en/v1.1.0#array\n"
    " [toml-table]: https://toml.io/en/v1.1.0#table\n"
    " [toml-inline]: https://toml.io/en/v1.1.0#inline-table\n"
    " [toml-AoT]: https://toml.io/en/v1.1.0#array-of-tables\n"
    " [gleam_time]: https://gleam-time.hexdocs.pm\n"
    " [rfc3339]: https://tools.ietf.org/html/rfc3339\n"
).

-opaque value() :: {toml_array, list(value())} |
    {toml_basic_string, gleam@option:option(binary()), binary()} |
    {toml_binary_int, gleam@option:option(binary()), integer()} |
    {toml_bool, boolean()} |
    {toml_float, gleam@option:option(binary()), float()} |
    {toml_hex_int, gleam@option:option(binary()), integer()} |
    {toml_infinity, sign()} |
    {toml_inline_table, list({binary(), value()})} |
    {toml_int, gleam@option:option(binary()), integer()} |
    {toml_literal_string, binary()} |
    {toml_local_date, binary()} |
    {toml_local_date_time, binary()} |
    {toml_local_time, binary()} |
    {toml_multiline_basic_string,
        gleam@option:option(binary()),
        binary(),
        boolean()} |
    {toml_multiline_literal_string, binary(), boolean()} |
    {toml_na_n, sign()} |
    {toml_octal_int, gleam@option:option(binary()), integer()} |
    {toml_offset_date_time, binary()} |
    {toml_array_of_tables, list(value())} |
    {toml_table, list({binary(), value()})} |
    {toml_invalid, binary()}.

-type sign() :: unsigned | positive | negative.

-file("src/molt/value.gleam", 278).
?DOC(
    " Creates a basic string Value. TOML basic strings process escape characters\n"
    " and bare newlines are not permitted.\n"
    "\n"
    " `constructor`\n"
).
-spec basic_string(binary()) -> value().
basic_string(Value) ->
    {toml_basic_string, none, Value}.

-file("src/molt/value.gleam", 1613).
-spec is_control_or_del(binary()) -> boolean().
is_control_or_del(Char) ->
    case gleam@string:to_utf_codepoints(Char) of
        [Cp] ->
            Codepoint = gleam_stdlib:identity(Cp),
            (Codepoint =< 16#1F) orelse (Codepoint =:= 16#7F);

        _ ->
            false
    end.

-file("src/molt/value.gleam", 1589).
-spec has_disallowed_literal_char(binary()) -> boolean().
has_disallowed_literal_char(Text) ->
    _pipe = gleam@string:to_graphemes(Text),
    gleam@list:any(_pipe, fun(Char) -> case Char of
                <<"\t"/utf8>> ->
                    false;

                <<"'"/utf8>> ->
                    true;

                <<"\n"/utf8>> ->
                    true;

                <<"\r"/utf8>> ->
                    true;

                _ ->
                    is_control_or_del(Char)
            end end).

-file("src/molt/value.gleam", 392).
?DOC(
    " Create a boolean Value.\n"
    "\n"
    " `constructor`\n"
).
-spec bool(boolean()) -> value().
bool(Value) ->
    {toml_bool, Value}.

-file("src/molt/value.gleam", 297).
?DOC(
    " Creates a literal string Value. TOML literal strings do not process escape\n"
    " characters and bare newlines are not permitted.\n"
    "\n"
    " Returns a `ValueParseError` if `value` contains `'`, a newline, a carriage\n"
    " return, or any control character other than tab.\n"
    "\n"
    " `constructor`\n"
).
-spec literal_string(binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
literal_string(Value) ->
    gleam@bool:guard(
        has_disallowed_literal_char(Value),
        {error, {value_parse_error, {some, <<"literal_string"/utf8>>}, Value}},
        fun() -> {ok, {toml_literal_string, Value}} end
    ).

-file("src/molt/value.gleam", 286).
?DOC(
    " Creates a multiline basic string Value. TOML basic strings process escape\n"
    " characters. Bare newlines are permitted.\n"
    "\n"
    " `constructor`\n"
).
-spec multiline_basic_string(binary()) -> value().
multiline_basic_string(Value) ->
    {toml_multiline_basic_string, none, Value, true}.

-file("src/molt/value.gleam", 1600).
-spec has_disallowed_multiline_literal_char(binary()) -> boolean().
has_disallowed_multiline_literal_char(Text) ->
    gleam_stdlib:contains_string(Text, <<"'''"/utf8>>) orelse begin
        _pipe = gleam@string:to_graphemes(Text),
        gleam@list:any(_pipe, fun(Char) -> case Char of
                    <<"\t"/utf8>> ->
                        false;

                    <<"\n"/utf8>> ->
                        false;

                    <<"\r"/utf8>> ->
                        false;

                    _ ->
                        is_control_or_del(Char)
                end end)
    end.

-file("src/molt/value.gleam", 315).
?DOC(
    " Creates a multiline literal string Value. TOML literal strings do not\n"
    " process escape characters. Bare newlines are permitted.\n"
    "\n"
    " Returns a `ValueParseError` if `value` contains `'''` or any control\n"
    " character other than tab, LF, or CR.\n"
    "\n"
    " `constructor`\n"
).
-spec multiline_literal_string(binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
multiline_literal_string(Value) ->
    gleam@bool:guard(
        has_disallowed_multiline_literal_char(Value),
        {error,
            {value_parse_error,
                {some, <<"multiline_literal_string"/utf8>>},
                Value}},
        fun() -> {ok, {toml_multiline_literal_string, Value, true}} end
    ).

-file("src/molt/value.gleam", 247).
?DOC(
    " Create a string Value. This will attempt to guess the correct type of TOML\n"
    " string to use, falling back to a `basic` or `multiline basic` string.\n"
    "\n"
    " `constructor`\n"
).
-spec string(binary()) -> value().
string(Value) ->
    Basic_would_escape = gleam_stdlib:contains_string(Value, <<"\""/utf8>>)
    orelse gleam_stdlib:contains_string(Value, <<"\\"/utf8>>),
    Has_newline = gleam_stdlib:contains_string(Value, <<"\n"/utf8>>),
    gleam@bool:lazy_guard(
        Has_newline andalso Basic_would_escape,
        fun() -> _pipe = multiline_literal_string(Value),
            gleam@result:lazy_unwrap(
                _pipe,
                fun() -> multiline_basic_string(Value) end
            ) end,
        fun() ->
            gleam@bool:guard(
                Has_newline,
                multiline_basic_string(Value),
                fun() ->
                    gleam@bool:lazy_guard(
                        Basic_would_escape,
                        fun() -> _pipe@1 = literal_string(Value),
                            gleam@result:lazy_unwrap(
                                _pipe@1,
                                fun() -> basic_string(Value) end
                            ) end,
                        fun() -> basic_string(Value) end
                    )
                end
            )
        end
    ).

-file("src/molt/value.gleam", 329).
?DOC(
    " Create an integer Value.\n"
    "\n"
    " `constructor`\n"
).
-spec int(integer()) -> value().
int(Value) ->
    {toml_int, none, Value}.

-file("src/molt/value.gleam", 336).
?DOC(
    " Create a integer Value encoded as hex (`0xff`).\n"
    "\n"
    " `constructor`\n"
).
-spec hex_int(integer()) -> value().
hex_int(Value) ->
    {toml_hex_int, none, Value}.

-file("src/molt/value.gleam", 343).
?DOC(
    " Create a integer Value encoded as octal (`0o67`).\n"
    "\n"
    " `constructor`\n"
).
-spec octal_int(integer()) -> value().
octal_int(Value) ->
    {toml_octal_int, none, Value}.

-file("src/molt/value.gleam", 350).
?DOC(
    " Create a integer Value encoded as binary (`0b1001`).\n"
    "\n"
    " `constructor`\n"
).
-spec binary_int(integer()) -> value().
binary_int(Value) ->
    {toml_binary_int, none, Value}.

-file("src/molt/value.gleam", 357).
?DOC(
    " Create a float Value.\n"
    "\n"
    " `constructor`\n"
).
-spec float(float()) -> value().
float(Value) ->
    {toml_float, none, Value}.

-file("src/molt/value.gleam", 364).
?DOC(
    " Create a unsigned infinity Value.\n"
    "\n"
    " `constructor`\n"
).
-spec infinity() -> value().
infinity() ->
    {toml_infinity, unsigned}.

-file("src/molt/value.gleam", 371).
?DOC(
    " Create a signed infinity Value.\n"
    "\n"
    " `constructor`\n"
).
-spec signed_infinity(sign()) -> value().
signed_infinity(Sign) ->
    {toml_infinity, Sign}.

-file("src/molt/value.gleam", 378).
?DOC(
    " Create a unsigned NaN Value.\n"
    "\n"
    " `constructor`\n"
).
-spec nan() -> value().
nan() ->
    {toml_na_n, unsigned}.

-file("src/molt/value.gleam", 385).
?DOC(
    " Create a signed NaN Value.\n"
    "\n"
    " `constructor`\n"
).
-spec signed_nan(sign()) -> value().
signed_nan(Sign) ->
    {toml_na_n, Sign}.

-file("src/molt/value.gleam", 402).
?DOC(
    " Creates a date-time, date, or time Value from an RFC3339-compatible `text`\n"
    " value. See [Date and Time Values](#date-and-time-values).\n"
    "\n"
    " Returns a `ValueParseError` if the `text` cannot be parsed.\n"
    "\n"
    " `constructor`\n"
).
-spec datetime(binary()) -> {ok, value()} | {error, molt@error:molt_error()}.
datetime(Text) ->
    case molt@internal@classifier:match_datetime(Text) of
        {some, offset_date_time} ->
            {ok, {toml_offset_date_time, Text}};

        {some, local_date_time} ->
            {ok, {toml_local_date_time, Text}};

        {some, local_date} ->
            {ok, {toml_local_date, Text}};

        {some, local_time} ->
            {ok, {toml_local_time, Text}};

        _ ->
            {error,
                {value_parse_error,
                    {some,
                        <<"offset_datetime, local_datetime, local_date, or local_time"/utf8>>},
                    Text}}
    end.

-file("src/molt/value.gleam", 424).
?DOC(
    " Creates an offset date-time Value.\n"
    "\n"
    " Returns a `ValueParseError` if the `text` cannot be parsed as an offset\n"
    " date-time value.\n"
    "\n"
    " `constructor`\n"
).
-spec offset_datetime(binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
offset_datetime(Text) ->
    case molt@internal@classifier:match_datetime(Text) of
        {some, offset_date_time} ->
            {ok, {toml_offset_date_time, Text}};

        _ ->
            {error,
                {value_parse_error, {some, <<"offset_datetime"/utf8>>}, Text}}
    end.

-file("src/molt/value.gleam", 437).
?DOC(
    " Creates a local date-time Value.\n"
    "\n"
    " Returns a `ValueParseError` if the `text` cannot be parsed as a local\n"
    " date-time value.\n"
    "\n"
    " `constructor`\n"
).
-spec local_datetime(binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
local_datetime(Text) ->
    case molt@internal@classifier:match_datetime(Text) of
        {some, local_date_time} ->
            {ok, {toml_local_date_time, Text}};

        _ ->
            {error,
                {value_parse_error, {some, <<"local_datetime"/utf8>>}, Text}}
    end.

-file("src/molt/value.gleam", 450).
?DOC(
    " Creates a local date Value.\n"
    "\n"
    " Returns a `ValueParseError` if the `text` cannot be parsed as a local date\n"
    " value.\n"
    "\n"
    " `constructor`\n"
).
-spec local_date(binary()) -> {ok, value()} | {error, molt@error:molt_error()}.
local_date(Text) ->
    case molt@internal@classifier:match_datetime(Text) of
        {some, local_date} ->
            {ok, {toml_local_date, Text}};

        _ ->
            {error, {value_parse_error, {some, <<"local_date"/utf8>>}, Text}}
    end.

-file("src/molt/value.gleam", 463).
?DOC(
    " Creates a local time Value.\n"
    "\n"
    " Returns a `ValueParseError` if the `text` cannot be parsed as a local time\n"
    " value.\n"
    "\n"
    " `constructor`\n"
).
-spec local_time(binary()) -> {ok, value()} | {error, molt@error:molt_error()}.
local_time(Text) ->
    case molt@internal@classifier:match_datetime(Text) of
        {some, local_time} ->
            {ok, {toml_local_time, Text}};

        _ ->
            {error, {value_parse_error, {some, <<"local_time"/utf8>>}, Text}}
    end.

-file("src/molt/value.gleam", 473).
?DOC(
    " Create an inline table Value from the entries.\n"
    "\n"
    " `constructor`\n"
).
-spec table(list({binary(), value()})) -> value().
table(Entries) ->
    {toml_inline_table, Entries}.

-file("src/molt/value.gleam", 483).
?DOC(
    " Create an inline table Value from a Dict.\n"
    "\n"
    " The order of keys in the inline table is non-deterministic but fixed at time\n"
    " of creation.\n"
    "\n"
    " `constructor`\n"
).
-spec table_from_dict(gleam@dict:dict(binary(), value())) -> value().
table_from_dict(Entries) ->
    {toml_inline_table, maps:to_list(Entries)}.

-file("src/molt/value.gleam", 490).
?DOC(
    " Create an array Value.\n"
    "\n"
    " `constructor`\n"
).
-spec array(list(value())) -> value().
array(Items) ->
    {toml_array, Items}.

-file("src/molt/value.gleam", 716).
?DOC(
    " Returns the TOML type name for a Value.\n"
    "\n"
    " Strings and integers have attached styles that can be retrieved with\n"
    " `string_style` and `int_style`.\n"
    "\n"
    " `introspection`\n"
).
-spec type_of(value()) -> binary().
type_of(Value) ->
    case Value of
        {toml_basic_string, _, _} ->
            <<"string"/utf8>>;

        {toml_multiline_basic_string, _, _, _} ->
            <<"string"/utf8>>;

        {toml_literal_string, _} ->
            <<"string"/utf8>>;

        {toml_multiline_literal_string, _, _} ->
            <<"string"/utf8>>;

        {toml_int, _, _} ->
            <<"integer"/utf8>>;

        {toml_hex_int, _, _} ->
            <<"integer"/utf8>>;

        {toml_octal_int, _, _} ->
            <<"integer"/utf8>>;

        {toml_binary_int, _, _} ->
            <<"integer"/utf8>>;

        {toml_float, _, _} ->
            <<"float"/utf8>>;

        {toml_infinity, _} ->
            <<"infinity"/utf8>>;

        {toml_na_n, _} ->
            <<"nan"/utf8>>;

        {toml_bool, _} ->
            <<"boolean"/utf8>>;

        {toml_array, _} ->
            <<"array"/utf8>>;

        {toml_array_of_tables, _} ->
            <<"array_of_tables"/utf8>>;

        {toml_table, _} ->
            <<"table"/utf8>>;

        {toml_inline_table, _} ->
            <<"inline_table"/utf8>>;

        {toml_offset_date_time, _} ->
            <<"offset_datetime"/utf8>>;

        {toml_local_date_time, _} ->
            <<"local_datetime"/utf8>>;

        {toml_local_date, _} ->
            <<"local_date"/utf8>>;

        {toml_local_time, _} ->
            <<"local_time"/utf8>>;

        {toml_invalid, _} ->
            <<"invalid"/utf8>>
    end.

-file("src/molt/value.gleam", 1548).
-spec type_mismatch(value(), binary()) -> molt@error:molt_error().
type_mismatch(Value, Expected) ->
    {type_mismatch, none, Expected, type_of(Value)}.

-file("src/molt/value.gleam", 499).
?DOC(
    " Coerces a table-like value to an inline table.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not table-shaped.\n"
    "\n"
    " `coercion`\n"
).
-spec as_inline_table(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_inline_table(Value) ->
    case Value of
        {toml_inline_table, _} = Self ->
            {ok, Self};

        {toml_table, Entries} ->
            {ok, {toml_inline_table, Entries}};

        _ ->
            {error, type_mismatch(Value, <<"table or inline_table"/utf8>>)}
    end.

-file("src/molt/value.gleam", 512).
?DOC(
    " Coerces a table-like value to a table with a section header.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not table-shaped.\n"
    "\n"
    " `coercion`\n"
).
-spec as_section_table(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_section_table(Value) ->
    case Value of
        {toml_table, _} = Self ->
            {ok, Self};

        {toml_inline_table, Entries} ->
            {ok, {toml_table, Entries}};

        _ ->
            {error, type_mismatch(Value, <<"table or inline_table"/utf8>>)}
    end.

-file("src/molt/value.gleam", 529).
?DOC(
    " Coerces an array-like value to an array.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not array-shaped.\n"
    "\n"
    " When coercing an array of tables to an array, `as_array` will coerce the\n"
    " items with `as_inline_table`, returning an `InvalidOperation` if any item\n"
    " fails to convert.\n"
    "\n"
    " `coercion`\n"
).
-spec as_array(value()) -> {ok, value()} | {error, molt@error:molt_error()}.
as_array(Value) ->
    case Value of
        {toml_array, _} = Self ->
            {ok, Self};

        {toml_array_of_tables, Items} ->
            _pipe = gleam@list:try_map(Items, fun as_inline_table/1),
            _pipe@1 = gleam@result:map(
                _pipe,
                fun(_capture) -> {toml_array, _capture} end
            ),
            gleam@result:replace_error(
                _pipe@1,
                {invalid_operation,
                    <<"as_array"/utf8>>,
                    {some,
                        <<"array_of_tables contains one or more non-table items"/utf8>>}}
            );

        _ ->
            {error, type_mismatch(Value, <<"array or array_of_tables"/utf8>>)}
    end.

-file("src/molt/value.gleam", 551).
?DOC(
    " Coerces an array-like value containing table-like values to an array of\n"
    " tables.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not array-shaped. If any\n"
    " value in the provided array is not table-like, an `InvalidOperation` error\n"
    " will be returned.\n"
    "\n"
    " `coercion`\n"
).
-spec as_array_of_tables(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_array_of_tables(Value) ->
    case Value of
        {toml_array_of_tables, _} = Self ->
            {ok, Self};

        {toml_array, Items} ->
            _pipe = gleam@list:try_map(Items, fun as_section_table/1),
            _pipe@1 = gleam@result:map(
                _pipe,
                fun(_capture) -> {toml_array_of_tables, _capture} end
            ),
            gleam@result:replace_error(
                _pipe@1,
                {invalid_operation,
                    <<"as_array_of_tables"/utf8>>,
                    {some,
                        <<"array contains one or more non-table items"/utf8>>}}
            );

        _ ->
            {error, type_mismatch(Value, <<"array or array_of_tables"/utf8>>)}
    end.

-file("src/molt/value.gleam", 570).
?DOC(
    " Coerces an integer variant to decimal representation.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not an integer.\n"
    "\n"
    " `coercion`\n"
).
-spec as_decimal_int(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_decimal_int(Value) ->
    case Value of
        {toml_int, _, _} = Self ->
            {ok, Self};

        {toml_hex_int, _, Value@1} ->
            {ok, {toml_int, none, Value@1}};

        {toml_octal_int, _, Value@1} ->
            {ok, {toml_int, none, Value@1}};

        {toml_binary_int, _, Value@1} ->
            {ok, {toml_int, none, Value@1}};

        _ ->
            {error, type_mismatch(Value, <<"integer"/utf8>>)}
    end.

-file("src/molt/value.gleam", 585).
?DOC(
    " Coerces an integer variant to hex representation.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not an integer.\n"
    "\n"
    " `coercion`\n"
).
-spec as_hex_int(value()) -> {ok, value()} | {error, molt@error:molt_error()}.
as_hex_int(Value) ->
    case Value of
        {toml_hex_int, _, _} = Self ->
            {ok, Self};

        {toml_int, _, Value@1} ->
            {ok, {toml_hex_int, none, Value@1}};

        {toml_octal_int, _, Value@1} ->
            {ok, {toml_hex_int, none, Value@1}};

        {toml_binary_int, _, Value@1} ->
            {ok, {toml_hex_int, none, Value@1}};

        _ ->
            {error, type_mismatch(Value, <<"integer"/utf8>>)}
    end.

-file("src/molt/value.gleam", 600).
?DOC(
    " Coerces an integer variant to octal representation.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not an integer.\n"
    "\n"
    " `coercion`\n"
).
-spec as_octal_int(value()) -> {ok, value()} | {error, molt@error:molt_error()}.
as_octal_int(Value) ->
    case Value of
        {toml_octal_int, _, _} = Self ->
            {ok, Self};

        {toml_int, _, Value@1} ->
            {ok, {toml_octal_int, none, Value@1}};

        {toml_hex_int, _, Value@1} ->
            {ok, {toml_octal_int, none, Value@1}};

        {toml_binary_int, _, Value@1} ->
            {ok, {toml_octal_int, none, Value@1}};

        _ ->
            {error, type_mismatch(Value, <<"integer"/utf8>>)}
    end.

-file("src/molt/value.gleam", 614).
?DOC(
    " Coerces an integer variant to binary representation.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not an integer.\n"
    "\n"
    " `coercion`\n"
).
-spec as_binary_int(value()) -> {ok, value()} | {error, molt@error:molt_error()}.
as_binary_int(Value) ->
    case Value of
        {toml_binary_int, _, _} = Self ->
            {ok, Self};

        {toml_int, _, Value@1} ->
            {ok, {toml_binary_int, none, Value@1}};

        {toml_hex_int, _, Value@1} ->
            {ok, {toml_binary_int, none, Value@1}};

        {toml_octal_int, _, Value@1} ->
            {ok, {toml_binary_int, none, Value@1}};

        _ ->
            {error, type_mismatch(Value, <<"integer"/utf8>>)}
    end.

-file("src/molt/value.gleam", 628).
?DOC(
    " Coerces a string to a basic (double-quoted, `\"`) string.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not a string.\n"
    "\n"
    " `coercion`\n"
).
-spec as_basic_string(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_basic_string(Value) ->
    case Value of
        {toml_basic_string, _, _} = Self ->
            {ok, Self};

        {toml_multiline_basic_string, _, Value@1, _} ->
            {ok, {toml_basic_string, none, Value@1}};

        {toml_literal_string, Value@1} ->
            {ok, {toml_basic_string, none, Value@1}};

        {toml_multiline_literal_string, Value@1, _} ->
            {ok, {toml_basic_string, none, Value@1}};

        _ ->
            {error, type_mismatch(Value, <<"string"/utf8>>)}
    end.

-file("src/molt/value.gleam", 644).
?DOC(
    " Coerces a string to a multiline basic (triple-double-quoted, `\"\"\"`) string.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not a string.\n"
    "\n"
    " `coercion`\n"
).
-spec as_multiline_basic_string(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_multiline_basic_string(Value) ->
    case Value of
        {toml_multiline_basic_string, _, _, _} = Self ->
            {ok, Self};

        {toml_basic_string, _, Value@1} ->
            {ok, {toml_multiline_basic_string, none, Value@1, true}};

        {toml_literal_string, Value@1} ->
            {ok, {toml_multiline_basic_string, none, Value@1, true}};

        {toml_multiline_literal_string, Value@1, _} ->
            {ok, {toml_multiline_basic_string, none, Value@1, true}};

        _ ->
            {error, type_mismatch(Value, <<"string"/utf8>>)}
    end.

-file("src/molt/value.gleam", 663).
?DOC(
    " Coerces a string to a literal (single-quoted, `'`) string.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not a string. Returns\n"
    " a `ValueParseError` if the content contains characters that cannot appear in\n"
    " a single-quoted literal string: `'`, newlines, or control characters other\n"
    " than tab.\n"
    "\n"
    " `coercion`\n"
).
-spec as_literal_string(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_literal_string(Value) ->
    case Value of
        {toml_literal_string, _} = Self ->
            {ok, Self};

        {toml_basic_string, _, Value@1} ->
            gleam@bool:guard(
                has_disallowed_literal_char(Value@1),
                {error,
                    {value_parse_error,
                        {some, <<"literal_string"/utf8>>},
                        Value@1}},
                fun() -> {ok, {toml_literal_string, Value@1}} end
            );

        {toml_multiline_basic_string, _, Value@1, _} ->
            gleam@bool:guard(
                has_disallowed_literal_char(Value@1),
                {error,
                    {value_parse_error,
                        {some, <<"literal_string"/utf8>>},
                        Value@1}},
                fun() -> {ok, {toml_literal_string, Value@1}} end
            );

        {toml_multiline_literal_string, Value@1, _} ->
            gleam@bool:guard(
                has_disallowed_literal_char(Value@1),
                {error,
                    {value_parse_error,
                        {some, <<"literal_string"/utf8>>},
                        Value@1}},
                fun() -> {ok, {toml_literal_string, Value@1}} end
            );

        _ ->
            {error, type_mismatch(Value, <<"string"/utf8>>)}
    end.

-file("src/molt/value.gleam", 691).
?DOC(
    " Coerces a string to a multiline literal (triple-single-quoted, `'''`)\n"
    " string.\n"
    "\n"
    " Returns a `TypeMismatch` error if the value is not a string. Returns\n"
    " a `ValueParseError` if the content contains `'''` or control characters not\n"
    " permitted in multiline literal strings (only tab, LF, and CR are allowed\n"
    " alongside other Unicode).\n"
    "\n"
    " `coercion`\n"
).
-spec as_multiline_literal_string(value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
as_multiline_literal_string(Value) ->
    case Value of
        {toml_multiline_literal_string, _, _} = Self ->
            {ok, Self};

        {toml_basic_string, _, Value@1} ->
            gleam@bool:guard(
                has_disallowed_multiline_literal_char(Value@1),
                {error,
                    {value_parse_error,
                        {some, <<"multiline_literal_string"/utf8>>},
                        Value@1}},
                fun() ->
                    {ok, {toml_multiline_literal_string, Value@1, true}}
                end
            );

        {toml_multiline_basic_string, _, Value@1, _} ->
            gleam@bool:guard(
                has_disallowed_multiline_literal_char(Value@1),
                {error,
                    {value_parse_error,
                        {some, <<"multiline_literal_string"/utf8>>},
                        Value@1}},
                fun() ->
                    {ok, {toml_multiline_literal_string, Value@1, true}}
                end
            );

        {toml_literal_string, Value@1} ->
            gleam@bool:guard(
                has_disallowed_multiline_literal_char(Value@1),
                {error,
                    {value_parse_error,
                        {some, <<"multiline_literal_string"/utf8>>},
                        Value@1}},
                fun() ->
                    {ok, {toml_multiline_literal_string, Value@1, true}}
                end
            );

        _ ->
            {error, type_mismatch(Value, <<"string"/utf8>>)}
    end.

-file("src/molt/value.gleam", 1493).
-spec escape_basic_pad_hex(binary(), integer()) -> binary().
escape_basic_pad_hex(Hex, Width) ->
    Len = string:length(Hex),
    gleam@bool:guard(
        Len >= Width,
        Hex,
        fun() ->
            <<(gleam@string:repeat(<<"0"/utf8>>, Width - Len))/binary,
                Hex/binary>>
        end
    ).

-file("src/molt/value.gleam", 1479).
-spec escape_control_char(binary()) -> binary().
escape_control_char(Char) ->
    case gleam@string:to_utf_codepoints(Char) of
        [Cp] ->
            Codepoint = gleam_stdlib:identity(Cp),
            gleam@bool:guard(
                not ((Codepoint =< 16#1F) orelse (Codepoint =:= 16#7F)),
                Char,
                fun() ->
                    <<"\\u"/utf8,
                        (escape_basic_pad_hex(gleam@int:to_base16(Codepoint), 4))/binary>>
                end
            );

        _ ->
            Char
    end.

-file("src/molt/value.gleam", 1468).
-spec escape_multiline_basic_char(binary()) -> binary().
escape_multiline_basic_char(Char) ->
    case Char of
        <<"\\"/utf8>> ->
            <<"\\\\"/utf8>>;

        <<"\""/utf8>> ->
            <<"\\\""/utf8>>;

        <<"\t"/utf8>> ->
            Char;

        <<"\n"/utf8>> ->
            Char;

        <<"\r"/utf8>> ->
            Char;

        <<"\x{0008}"/utf8>> ->
            <<"\\b"/utf8>>;

        <<"\x{000C}"/utf8>> ->
            <<"\\f"/utf8>>;

        _ ->
            escape_control_char(Char)
    end.

-file("src/molt/value.gleam", 1448).
-spec escape_multiline_basic(binary()) -> binary().
escape_multiline_basic(Value) ->
    _pipe = Value,
    _pipe@1 = gleam@string:to_graphemes(_pipe),
    _pipe@2 = gleam@list:map(_pipe@1, fun escape_multiline_basic_char/1),
    gleam@string:join(_pipe@2, <<""/utf8>>).

-file("src/molt/value.gleam", 1455).
-spec escape_basic_char(binary()) -> binary().
escape_basic_char(Char) ->
    case Char of
        <<"\\"/utf8>> ->
            <<"\\\\"/utf8>>;

        <<"\""/utf8>> ->
            <<"\\\""/utf8>>;

        <<"\t"/utf8>> ->
            <<"\\t"/utf8>>;

        <<"\n"/utf8>> ->
            <<"\\n"/utf8>>;

        <<"\r"/utf8>> ->
            <<"\\r"/utf8>>;

        <<"\x{0008}"/utf8>> ->
            <<"\\b"/utf8>>;

        <<"\x{000C}"/utf8>> ->
            <<"\\f"/utf8>>;

        _ ->
            escape_control_char(Char)
    end.

-file("src/molt/value.gleam", 1441).
-spec escape_basic(binary()) -> binary().
escape_basic(Value) ->
    _pipe = Value,
    _pipe@1 = gleam@string:to_graphemes(_pipe),
    _pipe@2 = gleam@list:map(_pipe@1, fun escape_basic_char/1),
    gleam@string:join(_pipe@2, <<""/utf8>>).

-file("src/molt/value.gleam", 1510).
-spec serialize_table_entries(list({binary(), value()})) -> list(binary()).
serialize_table_entries(Entries) ->
    gleam@list:map(
        Entries,
        fun(Entry) ->
            {Key, Value} = Entry,
            <<<<(molt@internal@utils:quote_key(Key))/binary, " = "/utf8>>/binary,
                (to_toml_value(Value))/binary>>
        end
    ).

-file("src/molt/value.gleam", 1500).
-spec serialize_inline_table(list({binary(), value()})) -> binary().
serialize_inline_table(Entries) ->
    Inner = begin
        _pipe = serialize_table_entries(Entries),
        gleam@string:join(_pipe, <<", "/utf8>>)
    end,
    <<<<"{"/utf8, Inner/binary>>/binary, "}"/utf8>>.

-file("src/molt/value.gleam", 1505).
-spec serialize_table_body(list({binary(), value()})) -> binary().
serialize_table_body(Entries) ->
    _pipe = serialize_table_entries(Entries),
    gleam@string:join(_pipe, <<"\n"/utf8>>).

-file("src/molt/value.gleam", 1436).
-spec serialize_array(list(value())) -> binary().
serialize_array(Items) ->
    Inner = begin
        _pipe = gleam@list:map(Items, fun to_toml_value/1),
        gleam@string:join(_pipe, <<", "/utf8>>)
    end,
    <<<<"["/utf8, Inner/binary>>/binary, "]"/utf8>>.

-file("src/molt/value.gleam", 1170).
?DOC(false).
-spec to_toml_value(value()) -> binary().
to_toml_value(Value) ->
    case Value of
        {toml_basic_string, {some, T}, _} ->
            T;

        {toml_multiline_basic_string, {some, T}, _, _} ->
            T;

        {toml_basic_string, none, Value@1} ->
            <<<<"\""/utf8, (escape_basic(Value@1))/binary>>/binary, "\""/utf8>>;

        {toml_multiline_basic_string, none, Value@2, true} ->
            <<<<"\"\"\"\n"/utf8, (escape_multiline_basic(Value@2))/binary>>/binary,
                "\"\"\""/utf8>>;

        {toml_multiline_basic_string, none, Value@3, false} ->
            <<<<"\"\"\""/utf8, (escape_multiline_basic(Value@3))/binary>>/binary,
                "\"\"\""/utf8>>;

        {toml_literal_string, Value@4} ->
            <<<<"'"/utf8, Value@4/binary>>/binary, "'"/utf8>>;

        {toml_multiline_literal_string, Value@5, true} ->
            <<<<"'''\n"/utf8, Value@5/binary>>/binary, "'''"/utf8>>;

        {toml_multiline_literal_string, Value@6, false} ->
            <<<<"'''"/utf8, Value@6/binary>>/binary, "'''"/utf8>>;

        {toml_int, {some, T@1}, _} ->
            T@1;

        {toml_int, none, Value@7} ->
            erlang:integer_to_binary(Value@7);

        {toml_hex_int, {some, T@2}, _} ->
            T@2;

        {toml_hex_int, none, Value@8} ->
            <<"0x"/utf8, (gleam@int:to_base16(Value@8))/binary>>;

        {toml_octal_int, {some, T@3}, _} ->
            T@3;

        {toml_octal_int, none, Value@9} ->
            <<"0o"/utf8, (gleam@int:to_base8(Value@9))/binary>>;

        {toml_binary_int, {some, T@4}, _} ->
            T@4;

        {toml_binary_int, none, Value@10} ->
            <<"0b"/utf8, (gleam@int:to_base2(Value@10))/binary>>;

        {toml_float, {some, T@5}, _} ->
            T@5;

        {toml_float, none, Value@11} ->
            gleam_stdlib:float_to_string(Value@11);

        {toml_infinity, unsigned} ->
            <<"inf"/utf8>>;

        {toml_infinity, positive} ->
            <<"+inf"/utf8>>;

        {toml_infinity, negative} ->
            <<"-inf"/utf8>>;

        {toml_na_n, unsigned} ->
            <<"nan"/utf8>>;

        {toml_na_n, positive} ->
            <<"+nan"/utf8>>;

        {toml_na_n, negative} ->
            <<"-nan"/utf8>>;

        {toml_bool, true} ->
            <<"true"/utf8>>;

        {toml_bool, false} ->
            <<"false"/utf8>>;

        {toml_offset_date_time, Text} ->
            Text;

        {toml_local_date_time, Text@1} ->
            Text@1;

        {toml_local_date, Text@2} ->
            Text@2;

        {toml_local_time, Text@3} ->
            Text@3;

        {toml_array, Items} ->
            serialize_array(Items);

        {toml_array_of_tables, Items} ->
            serialize_array(Items);

        {toml_table, Entries} ->
            serialize_table_body(Entries);

        {toml_inline_table, Entries@1} ->
            serialize_inline_table(Entries@1);

        {toml_invalid, Text@4} ->
            Text@4
    end.

-file("src/molt/value.gleam", 743).
?DOC(
    " Returns a debug string representation of a Value.\n"
    "\n"
    " `introspection`\n"
).
-spec inspect(value()) -> binary().
inspect(Value) ->
    <<<<<<(type_of(Value))/binary, "("/utf8>>/binary,
            (to_toml_value(Value))/binary>>/binary,
        ")"/utf8>>.

-file("src/molt/value.gleam", 750).
?DOC(
    " Returns the raw text of a `TomlInvalid` value, or empty string otherwise.\n"
    "\n"
    " `introspection`\n"
).
-spec invalid_text(value()) -> binary().
invalid_text(Value) ->
    case Value of
        {toml_invalid, Text} ->
            Text;

        _ ->
            <<""/utf8>>
    end.

-file("src/molt/value.gleam", 760).
?DOC(
    " Returns the style of string Value, or None if not a string.\n"
    "\n"
    " `introspection`\n"
).
-spec string_style(value()) -> gleam@option:option(binary()).
string_style(Value) ->
    case Value of
        {toml_basic_string, _, _} ->
            {some, <<"basic"/utf8>>};

        {toml_multiline_basic_string, _, _, _} ->
            {some, <<"multiline_basic"/utf8>>};

        {toml_literal_string, _} ->
            {some, <<"literal"/utf8>>};

        {toml_multiline_literal_string, _, _} ->
            {some, <<"multiline_literal"/utf8>>};

        _ ->
            none
    end.

-file("src/molt/value.gleam", 773).
?DOC(
    " Returns the style of integer Value, or None if not an integer.\n"
    "\n"
    " `introspection`\n"
).
-spec int_style(value()) -> gleam@option:option(binary()).
int_style(Value) ->
    case Value of
        {toml_int, _, _} ->
            {some, <<"decimal"/utf8>>};

        {toml_hex_int, _, _} ->
            {some, <<"hex"/utf8>>};

        {toml_octal_int, _, _} ->
            {some, <<"octal"/utf8>>};

        {toml_binary_int, _, _} ->
            {some, <<"binary"/utf8>>};

        _ ->
            none
    end.

-file("src/molt/value.gleam", 1140).
?DOC(false).
-spec to_toml(binary(), value()) -> {ok, binary()} |
    {error, molt@error:molt_error()}.
to_toml(Key, Value) ->
    Key@1 = molt@internal@utils:quote_key(Key),
    case Value of
        {toml_table, Entries} ->
            {ok,
                <<<<<<<<"["/utf8, Key@1/binary>>/binary, "]\n"/utf8>>/binary,
                        (serialize_table_body(Entries))/binary>>/binary,
                    "\n"/utf8>>};

        {toml_array_of_tables, Items} ->
            _pipe = gleam@list:try_map(Items, fun(Entry) -> case Entry of
                        {toml_inline_table, Entries@1} ->
                            {ok,
                                <<<<<<<<"[["/utf8, Key@1/binary>>/binary,
                                            "]]\n"/utf8>>/binary,
                                        (serialize_table_body(Entries@1))/binary>>/binary,
                                    "\n"/utf8>>};

                        {toml_table, Entries@1} ->
                            {ok,
                                <<<<<<<<"[["/utf8, Key@1/binary>>/binary,
                                            "]]\n"/utf8>>/binary,
                                        (serialize_table_body(Entries@1))/binary>>/binary,
                                    "\n"/utf8>>};

                        _ ->
                            {error,
                                {type_mismatch,
                                    none,
                                    <<"table"/utf8>>,
                                    <<"non-table item in array table"/utf8>>}}
                    end end),
            gleam@result:map(
                _pipe,
                fun(_capture) -> gleam@string:join(_capture, <<"\n"/utf8>>) end
            );

        _ ->
            {ok,
                <<<<Key@1/binary, " = "/utf8>>/binary,
                    (to_toml_value(Value))/binary>>}
    end.

-file("src/molt/value.gleam", 790).
?DOC(
    " Returns True if a Value's text is syntactically valid TOML.\n"
    "\n"
    " Values created using the constructor functions (including `parse_value`) are\n"
    " guaranteed to be valid, but values retrieved from a TOML document with\n"
    " `molt/cst` functions may be invalid.\n"
    "\n"
    " `introspection`\n"
).
-spec is_valid(value()) -> boolean().
is_valid(Value) ->
    case Value of
        {toml_invalid, _} ->
            false;

        _ ->
            _pipe = to_toml(<<"_v"/utf8>>, Value),
            _pipe@1 = gleam@result:map(_pipe, fun molt@internal@parser:parse/1),
            gleam@result:is_ok(_pipe@1)
    end.

-file("src/molt/value.gleam", 803).
?DOC(
    " Unwraps the string Value or returns a `TypeMismatch` error.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_string(value()) -> {ok, binary()} |
    {error, molt@error:molt_error()}.
unwrap_string(Value) ->
    case Value of
        {toml_basic_string, _, Value@1} ->
            {ok, Value@1};

        {toml_multiline_basic_string, _, Value@1, _} ->
            {ok, Value@1};

        {toml_literal_string, Value@1} ->
            {ok, Value@1};

        {toml_multiline_literal_string, Value@1, _} ->
            {ok, Value@1};

        _ ->
            {error, type_mismatch(Value, <<"string"/utf8>>)}
    end.

-file("src/molt/value.gleam", 816).
?DOC(
    " Unwraps the string Value or returns the default.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_string_or(value(), binary()) -> binary().
unwrap_string_or(Value, Default) ->
    _pipe = unwrap_string(Value),
    gleam@result:unwrap(_pipe, Default).

-file("src/molt/value.gleam", 824).
?DOC(
    " Unwraps the integer Value or returns a `TypeMismatch` error.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_int(value()) -> {ok, integer()} | {error, molt@error:molt_error()}.
unwrap_int(Value) ->
    case Value of
        {toml_int, _, Value@1} ->
            {ok, Value@1};

        {toml_hex_int, _, Value@1} ->
            {ok, Value@1};

        {toml_octal_int, _, Value@1} ->
            {ok, Value@1};

        {toml_binary_int, _, Value@1} ->
            {ok, Value@1};

        _ ->
            {error, type_mismatch(Value, <<"integer"/utf8>>)}
    end.

-file("src/molt/value.gleam", 837).
?DOC(
    " Unwraps the integer Value or returns the default.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_int_or(value(), integer()) -> integer().
unwrap_int_or(Value, Default) ->
    _pipe = unwrap_int(Value),
    gleam@result:unwrap(_pipe, Default).

-file("src/molt/value.gleam", 845).
?DOC(
    " Unwraps the float Value or returns a `TypeMismatch` error.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_float(value()) -> {ok, float()} | {error, molt@error:molt_error()}.
unwrap_float(Value) ->
    case Value of
        {toml_float, _, Value@1} ->
            {ok, Value@1};

        _ ->
            {error, type_mismatch(Value, <<"float"/utf8>>)}
    end.

-file("src/molt/value.gleam", 855).
?DOC(
    " Unwraps the float Value or returns the default.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_float_or(value(), float()) -> float().
unwrap_float_or(Value, Default) ->
    _pipe = unwrap_float(Value),
    gleam@result:unwrap(_pipe, Default).

-file("src/molt/value.gleam", 863).
?DOC(
    " Unwraps the boolean Value or returns a `TypeMismatch` error.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_bool(value()) -> {ok, boolean()} | {error, molt@error:molt_error()}.
unwrap_bool(Value) ->
    case Value of
        {toml_bool, Value@1} ->
            {ok, Value@1};

        _ ->
            {error, type_mismatch(Value, <<"boolean"/utf8>>)}
    end.

-file("src/molt/value.gleam", 873).
?DOC(
    " Unwraps the boolean Value or returns the default.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_bool_or(value(), boolean()) -> boolean().
unwrap_bool_or(Value, Default) ->
    _pipe = unwrap_bool(Value),
    gleam@result:unwrap(_pipe, Default).

-file("src/molt/value.gleam", 882).
?DOC(
    " Unwraps the offset date-time, local date-time, local date, or local time\n"
    " Value as the constructed RFC3339 string or returns a `TypeMismatch` error.\n"
    "\n"
    " `value`\n"
).
-spec unwrap_datetime(value()) -> {ok, binary()} |
    {error, molt@error:molt_error()}.
unwrap_datetime(Value) ->
    case Value of
        {toml_local_date, Text} ->
            {ok, Text};

        {toml_local_date_time, Text} ->
            {ok, Text};

        {toml_local_time, Text} ->
            {ok, Text};

        {toml_offset_date_time, Text} ->
            {ok, Text};

        _ ->
            {error,
                type_mismatch(
                    Value,
                    <<"offset_datetime, local_datetime, local_date, or local_time"/utf8>>
                )}
    end.

-file("src/molt/value.gleam", 1552).
-spec require_array(
    value(),
    fun((list(value())) -> {ok, NDL} | {error, molt@error:molt_error()})
) -> {ok, NDL} | {error, molt@error:molt_error()}.
require_array(Value, Continue) ->
    case Value of
        {toml_array, Items} ->
            Continue(Items);

        {toml_array_of_tables, Items} ->
            Continue(Items);

        _ ->
            {error, type_mismatch(Value, <<"array"/utf8>>)}
    end.

-file("src/molt/value.gleam", 901).
?DOC(
    " Get the element at index from an array or array of tables Value.\n"
    "\n"
    " Negative indices count from the end of the array.\n"
    "\n"
    " `array`\n"
).
-spec array_get_at(value(), integer()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
array_get_at(Value, Index) ->
    require_array(
        Value,
        fun(Items) ->
            Length = erlang:length(Items),
            Resolved = molt@internal@utils:resolve_index(Index, Length),
            gleam@bool:guard(
                (Resolved < 0) orelse (Resolved >= Length),
                {error, {value_index_out_of_range, Index, Length}},
                fun() -> _pipe = molt@internal@utils:list_at(Items, Resolved),
                    gleam@result:replace_error(
                        _pipe,
                        {value_index_out_of_range, Index, Length}
                    ) end
            )
        end
    ).

-file("src/molt/value.gleam", 1572).
-spec rebuild_array(value(), list(value())) -> value().
rebuild_array(Original, New_items) ->
    case Original of
        {toml_array_of_tables, _} ->
            {toml_array_of_tables, New_items};

        _ ->
            {toml_array, New_items}
    end.

-file("src/molt/value.gleam", 924).
?DOC(
    " Replace the element at index in an array Value.\n"
    "\n"
    " Negative indices count from the end of the array.\n"
    "\n"
    " `array`\n"
).
-spec array_replace_at(value(), integer(), value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
array_replace_at(Value, Index, New) ->
    require_array(
        Value,
        fun(Items) ->
            Len = erlang:length(Items),
            Resolved = molt@internal@utils:resolve_index(Index, Len),
            gleam@bool:guard(
                (Resolved < 0) orelse (Resolved >= Len),
                {error, {value_index_out_of_range, Index, Len}},
                fun() ->
                    New_items = gleam@list:index_map(
                        Items,
                        fun(Item, I) -> case I =:= Resolved of
                                true ->
                                    New;

                                false ->
                                    Item
                            end end
                    ),
                    {ok, rebuild_array(Value, New_items)}
                end
            )
        end
    ).

-file("src/molt/value.gleam", 953).
?DOC(
    " Remove the element at index from the array Value.\n"
    "\n"
    " Negative indices count from the end of the array.\n"
    "\n"
    " `array`\n"
).
-spec array_remove_at(value(), integer()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
array_remove_at(Value, Index) ->
    require_array(
        Value,
        fun(Items) ->
            Len = erlang:length(Items),
            Resolved = molt@internal@utils:resolve_index(Index, Len),
            gleam@bool:guard(
                (Resolved < 0) orelse (Resolved >= Len),
                {error, {value_index_out_of_range, Index, Len}},
                fun() ->
                    New_items = begin
                        _pipe = gleam@list:index_fold(
                            Items,
                            [],
                            fun(Acc, Item, I) -> case I =:= Resolved of
                                    true ->
                                        Acc;

                                    false ->
                                        [Item | Acc]
                                end end
                        ),
                        lists:reverse(_pipe)
                    end,
                    {ok, rebuild_array(Value, New_items)}
                end
            )
        end
    ).

-file("src/molt/value.gleam", 980).
?DOC(
    " Insert an element before the given index. Negative indices count from end.\n"
    "\n"
    " `array`\n"
).
-spec array_insert_at(value(), integer(), value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
array_insert_at(Value, Index, New) ->
    require_array(
        Value,
        fun(Items) ->
            Len = erlang:length(Items),
            Resolved = molt@internal@utils:resolve_index(Index, Len),
            gleam@bool:guard(
                (Resolved < 0) orelse (Resolved > Len),
                {error, {value_index_out_of_range, Index, Len}},
                fun() ->
                    {Before, After} = gleam@list:split(Items, Resolved),
                    New_items = lists:append(Before, [New | After]),
                    {ok, rebuild_array(Value, New_items)}
                end
            )
        end
    ).

-file("src/molt/value.gleam", 1002).
?DOC(
    " Append an element to the end of an array.\n"
    "\n"
    " `array`\n"
).
-spec array_append(value(), value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
array_append(Value, New) ->
    require_array(
        Value,
        fun(Items) -> {ok, rebuild_array(Value, lists:append(Items, [New]))} end
    ).

-file("src/molt/value.gleam", 1013).
?DOC(
    " Extract the items list from an array value.\n"
    "\n"
    " `array`\n"
).
-spec array_to_list(value()) -> {ok, list(value())} |
    {error, molt@error:molt_error()}.
array_to_list(Value) ->
    require_array(Value, fun(Items) -> {ok, Items} end).

-file("src/molt/value.gleam", 1022).
?DOC(
    " Returns the size of an array. Returns `None` if the value provided is not an\n"
    " array.\n"
    "\n"
    " `array`\n"
).
-spec array_length(value()) -> gleam@option:option(integer()).
array_length(Value) ->
    case Value of
        {toml_array, Items} ->
            {some, erlang:length(Items)};

        {toml_array_of_tables, Items} ->
            {some, erlang:length(Items)};

        _ ->
            none
    end.

-file("src/molt/value.gleam", 1562).
-spec require_table(
    value(),
    fun((list({binary(), value()})) -> {ok, NDR} |
        {error, molt@error:molt_error()})
) -> {ok, NDR} | {error, molt@error:molt_error()}.
require_table(Value, Continue) ->
    case Value of
        {toml_table, Entries} ->
            Continue(Entries);

        {toml_inline_table, Entries} ->
            Continue(Entries);

        _ ->
            {error, type_mismatch(Value, <<"table"/utf8>>)}
    end.

-file("src/molt/value.gleam", 1032).
?DOC(
    " Get the value for a key in a table.\n"
    "\n"
    " `table`\n"
).
-spec table_get_key(value(), binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
table_get_key(Value, Key) ->
    require_table(
        Value,
        fun(Entries) ->
            case gleam@list:find(
                Entries,
                fun(Entry) -> erlang:element(1, Entry) =:= Key end
            ) of
                {ok, {_, V}} ->
                    {ok, V};

                {error, _} ->
                    {error, {value_key_not_found, Key}}
            end
        end
    ).

-file("src/molt/value.gleam", 1046).
?DOC(
    " Check if a key exists in a table.\n"
    "\n"
    " `table`\n"
).
-spec table_has_key(value(), binary()) -> boolean().
table_has_key(Value, Key) ->
    case Value of
        {toml_inline_table, Entries} ->
            gleam@list:any(
                Entries,
                fun(Entry) -> erlang:element(1, Entry) =:= Key end
            );

        {toml_table, Entries} ->
            gleam@list:any(
                Entries,
                fun(Entry) -> erlang:element(1, Entry) =:= Key end
            );

        _ ->
            false
    end.

-file("src/molt/value.gleam", 1057).
?DOC(
    " Get the list of key names from a table.\n"
    "\n"
    " `table`\n"
).
-spec table_keys(value()) -> {ok, list(binary())} |
    {error, molt@error:molt_error()}.
table_keys(Value) ->
    require_table(
        Value,
        fun(Entries) ->
            {ok,
                gleam@list:map(
                    Entries,
                    fun(Entry) -> erlang:element(1, Entry) end
                )}
        end
    ).

-file("src/molt/value.gleam", 1579).
-spec rebuild_table(value(), list({binary(), value()})) -> value().
rebuild_table(Original, New_entries) ->
    case Original of
        {toml_table, _} ->
            {toml_table, New_entries};

        _ ->
            {toml_inline_table, New_entries}
    end.

-file("src/molt/value.gleam", 1065).
?DOC(
    " Set or replace a key in a table. Appends if key doesn't exist.\n"
    "\n"
    " `table`\n"
).
-spec table_set_key(value(), binary(), value()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
table_set_key(Value, Key, New) ->
    require_table(
        Value,
        fun(Entries) ->
            New_entries = case gleam@list:any(
                Entries,
                fun(Entry) -> erlang:element(1, Entry) =:= Key end
            ) of
                true ->
                    gleam@list:map(
                        Entries,
                        fun(Entry@1) ->
                            case erlang:element(1, Entry@1) =:= Key of
                                true ->
                                    {Key, New};

                                false ->
                                    Entry@1
                            end
                        end
                    );

                false ->
                    lists:append(Entries, [{Key, New}])
            end,
            {ok, rebuild_table(Value, New_entries)}
        end
    ).

-file("src/molt/value.gleam", 1087).
?DOC(
    " Remove a key from a table.\n"
    "\n"
    " `table`\n"
).
-spec table_remove_key(value(), binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
table_remove_key(Value, Key) ->
    require_table(
        Value,
        fun(Entries) ->
            New_entries = gleam@list:filter(
                Entries,
                fun(Entry) -> erlang:element(1, Entry) /= Key end
            ),
            {ok, rebuild_table(Value, New_entries)}
        end
    ).

-file("src/molt/value.gleam", 1099).
?DOC(
    " Rename a key in a table. Errors if the key doesn't exist.\n"
    "\n"
    " `table`\n"
).
-spec table_rename_key(value(), binary(), binary()) -> {ok, value()} |
    {error, molt@error:molt_error()}.
table_rename_key(Value, From, To) ->
    require_table(
        Value,
        fun(Entries) ->
            gleam@bool:guard(
                not gleam@list:any(
                    Entries,
                    fun(Entry) -> erlang:element(1, Entry) =:= From end
                ),
                {error, {value_key_not_found, From}},
                fun() ->
                    New_entries = gleam@list:map(
                        Entries,
                        fun(Entry@1) ->
                            case erlang:element(1, Entry@1) =:= From of
                                true ->
                                    {To, erlang:element(2, Entry@1)};

                                false ->
                                    Entry@1
                            end
                        end
                    ),
                    {ok, rebuild_table(Value, New_entries)}
                end
            )
        end
    ).

-file("src/molt/value.gleam", 1124).
?DOC(
    " Extract the entries list from a table value.\n"
    "\n"
    " `table`\n"
).
-spec table_to_list(value()) -> {ok, list({binary(), value()})} |
    {error, molt@error:molt_error()}.
table_to_list(Value) ->
    require_table(Value, fun(Entries) -> {ok, Entries} end).

-file("src/molt/value.gleam", 1134).
?DOC(
    " Extract a Dict from a table value. Key order is lost.\n"
    "\n"
    " `table`\n"
).
-spec table_to_dict(value()) -> {ok, gleam@dict:dict(binary(), value())} |
    {error, molt@error:molt_error()}.
table_to_dict(Value) ->
    require_table(Value, fun(Entries) -> {ok, maps:from_list(Entries)} end).

-file("src/molt/value.gleam", 1432).
-spec strip_delims(binary(), integer()) -> binary().
strip_delims(Text, N) ->
    _pipe = gleam@string:drop_start(Text, N),
    gleam@string:drop_end(_pipe, N).

-file("src/molt/value.gleam", 1391).
-spec build_inline_table_entries(
    list({binary(), value()}),
    list(greenwood:element(molt@types:toml_kind()))
) -> list(greenwood:element(molt@types:toml_kind())).
build_inline_table_entries(Entries, Acc) ->
    case Entries of
        [] ->
            lists:reverse(Acc);

        [{Key, Val}] ->
            Kv = {node,
                key_value,
                [{token_element,
                        {token, bare_key, molt@internal@utils:quote_key(Key)}},
                    {token_element, {token, whitespace, <<" "/utf8>>}},
                    {token_element, {token, equals, <<""/utf8>>}},
                    {token_element, {token, whitespace, <<" "/utf8>>}},
                    to_cst(Val)],
                bare},
            lists:reverse([{node_element, Kv} | Acc]);

        [{Key@1, Val@1} | Rest] ->
            Kv@1 = {node,
                key_value,
                [{token_element,
                        {token, bare_key, molt@internal@utils:quote_key(Key@1)}},
                    {token_element, {token, whitespace, <<" "/utf8>>}},
                    {token_element, {token, equals, <<""/utf8>>}},
                    {token_element, {token, whitespace, <<" "/utf8>>}},
                    to_cst(Val@1),
                    {token_element, {token, comma, <<""/utf8>>}},
                    {token_element, {token, whitespace, <<" "/utf8>>}}],
                bare},
            build_inline_table_entries(Rest, [{node_element, Kv@1} | Acc])
    end.

-file("src/molt/value.gleam", 1381).
-spec build_inline_table_cst(list({binary(), value()})) -> greenwood:node_(molt@types:toml_kind()).
build_inline_table_cst(Entries) ->
    Children = begin
        _pipe = [{token_element, {token, left_brace, <<""/utf8>>}}],
        _pipe@1 = lists:append(_pipe, build_inline_table_entries(Entries, [])),
        lists:append(
            _pipe@1,
            [{token_element, {token, right_brace, <<""/utf8>>}}]
        )
    end,
    greenwood:node(inline_table, Children).

-file("src/molt/value.gleam", 1354).
-spec build_array_elements(
    list(value()),
    list(greenwood:element(molt@types:toml_kind()))
) -> list(greenwood:element(molt@types:toml_kind())).
build_array_elements(Items, Acc) ->
    case Items of
        [] ->
            lists:reverse(Acc);

        [Item] ->
            El = {node, array_element, [to_cst(Item)], bare},
            lists:reverse([{node_element, El} | Acc]);

        [Item@1 | Rest] ->
            El@1 = {node,
                array_element,
                [to_cst(Item@1),
                    {token_element, {token, comma, <<""/utf8>>}},
                    {token_element, {token, whitespace, <<" "/utf8>>}}],
                bare},
            build_array_elements(Rest, [{node_element, El@1} | Acc])
    end.

-file("src/molt/value.gleam", 1344).
-spec build_array_cst(list(value())) -> greenwood:node_(molt@types:toml_kind()).
build_array_cst(Items) ->
    Children = begin
        _pipe = [{token_element, {token, left_bracket, <<""/utf8>>}}],
        _pipe@1 = lists:append(_pipe, build_array_elements(Items, [])),
        lists:append(
            _pipe@1,
            [{token_element, {token, right_bracket, <<""/utf8>>}}]
        )
    end,
    greenwood:node(array, Children).

-file("src/molt/value.gleam", 1215).
?DOC(
    " Produce a syntax tree representation of the value suitable for use with\n"
    " `cst.set_kv_value`.\n"
).
-spec to_cst(value()) -> greenwood:element(molt@types:toml_kind()).
to_cst(Value) ->
    case Value of
        {toml_basic_string, {some, T}, _} ->
            {token_element, {token, basic_string, strip_delims(T, 1)}};

        {toml_basic_string, none, Value@1} ->
            {token_element, {token, basic_string, escape_basic(Value@1)}};

        {toml_multiline_basic_string, {some, T@1}, _, _} ->
            Raw = strip_delims(T@1, 3),
            {Kind, Content} = case Raw of
                <<"\r\n"/utf8, Rest/binary>> ->
                    {multiline_basic_string_nl, Rest};

                <<"\n"/utf8, Rest@1/binary>> ->
                    {multiline_basic_string_nl, Rest@1};

                _ ->
                    {multiline_basic_string, Raw}
            end,
            {token_element, {token, Kind, Content}};

        {toml_multiline_basic_string, none, Value@2, true} ->
            {token_element,
                {token,
                    multiline_basic_string_nl,
                    escape_multiline_basic(Value@2)}};

        {toml_multiline_basic_string, none, Value@3, false} ->
            {token_element,
                {token, multiline_basic_string, escape_multiline_basic(Value@3)}};

        {toml_literal_string, Value@4} ->
            {token_element, {token, literal_string, Value@4}};

        {toml_multiline_literal_string, Value@5, true} ->
            {token_element, {token, multiline_literal_string_nl, Value@5}};

        {toml_multiline_literal_string, Value@6, false} ->
            {token_element, {token, multiline_literal_string, Value@6}};

        {toml_int, {some, T@2}, _} ->
            {token_element, {token, integer, T@2}};

        {toml_int, none, Value@7} ->
            {token_element, {token, integer, erlang:integer_to_binary(Value@7)}};

        {toml_hex_int, {some, T@3}, _} ->
            {token_element, {token, hex_integer, T@3}};

        {toml_hex_int, none, Value@8} ->
            {token_element,
                {token,
                    hex_integer,
                    <<"0x"/utf8, (gleam@int:to_base16(Value@8))/binary>>}};

        {toml_octal_int, {some, T@4}, _} ->
            {token_element, {token, octal_integer, T@4}};

        {toml_octal_int, none, Value@9} ->
            {token_element,
                {token,
                    octal_integer,
                    <<"0o"/utf8, (gleam@int:to_base8(Value@9))/binary>>}};

        {toml_binary_int, {some, T@5}, _} ->
            {token_element, {token, binary_integer, T@5}};

        {toml_binary_int, none, Value@10} ->
            {token_element,
                {token,
                    binary_integer,
                    <<"0b"/utf8, (gleam@int:to_base2(Value@10))/binary>>}};

        {toml_float, {some, T@6}, _} ->
            {token_element, {token, float, T@6}};

        {toml_float, none, Value@11} ->
            {token_element,
                {token, float, gleam_stdlib:float_to_string(Value@11)}};

        {toml_infinity, unsigned} ->
            {token_element, {token, inf, <<""/utf8>>}};

        {toml_infinity, positive} ->
            {token_element, {token, pos_inf, <<""/utf8>>}};

        {toml_infinity, negative} ->
            {token_element, {token, neg_inf, <<""/utf8>>}};

        {toml_na_n, unsigned} ->
            {token_element, {token, na_n, <<""/utf8>>}};

        {toml_na_n, positive} ->
            {token_element, {token, pos_na_n, <<""/utf8>>}};

        {toml_na_n, negative} ->
            {token_element, {token, neg_na_n, <<""/utf8>>}};

        {toml_bool, true} ->
            {token_element, {token, bool_true, <<""/utf8>>}};

        {toml_bool, false} ->
            {token_element, {token, bool_false, <<""/utf8>>}};

        {toml_offset_date_time, Text} ->
            {token_element, {token, offset_date_time, Text}};

        {toml_local_date_time, Text@1} ->
            {token_element, {token, local_date_time, Text@1}};

        {toml_local_date, Text@2} ->
            {token_element, {token, local_date, Text@2}};

        {toml_local_time, Text@3} ->
            {token_element, {token, local_time, Text@3}};

        {toml_array, Items} ->
            {node_element, build_array_cst(Items)};

        {toml_inline_table, Entries} ->
            {node_element, build_inline_table_cst(Entries)};

        {toml_array_of_tables, Items@1} ->
            {node_element, build_array_cst(Items@1)};

        {toml_table, Entries@1} ->
            {node_element, build_inline_table_cst(Entries@1)};

        {toml_invalid, Text@4} ->
            {token_element, {token, invalid_value, Text@4}}
    end.

-file("src/molt/value.gleam", 1718).
-spec invalid(binary()) -> value().
invalid(Text) ->
    {toml_invalid, Text}.

-file("src/molt/value.gleam", 1536).
-spec parse_float(binary()) -> value().
parse_float(Text) ->
    _pipe = case {gleam_stdlib:contains_string(Text, <<"."/utf8>>),
        gleam_stdlib:contains_string(Text, <<"e"/utf8>>)} of
        {true, _} ->
            Text;

        {_, true} ->
            gleam@string:replace(Text, <<"e"/utf8>>, <<".0e"/utf8>>);

        {_, _} ->
            <<Text/binary, ".0"/utf8>>
    end,
    _pipe@1 = gleam@string:replace(_pipe, <<"_"/utf8>>, <<""/utf8>>),
    _pipe@2 = gleam_stdlib:parse_float(_pipe@1),
    _pipe@3 = gleam@result:map(
        _pipe@2,
        fun(Float) -> {toml_float, {some, Text}, Float} end
    ),
    gleam@result:unwrap(_pipe@3, invalid(Text)).

-file("src/molt/value.gleam", 1517).
-spec parse_base(binary(), integer()) -> value().
parse_base(Text, Base) ->
    _pipe = case Text of
        <<"0x"/utf8, Text@1/binary>> ->
            Text@1;

        <<"0o"/utf8, Text@1/binary>> ->
            Text@1;

        <<"0b"/utf8, Text@1/binary>> ->
            Text@1;

        _ ->
            Text
    end,
    _pipe@1 = gleam@string:replace(_pipe, <<"_"/utf8>>, <<""/utf8>>),
    _pipe@2 = gleam@int:base_parse(_pipe@1, Base),
    _pipe@3 = gleam@result:map(_pipe@2, fun(Value) -> case Base of
                2 ->
                    {toml_binary_int, {some, Text}, Value};

                8 ->
                    {toml_octal_int, {some, Text}, Value};

                10 ->
                    {toml_int, {some, Text}, Value};

                16 ->
                    {toml_hex_int, {some, Text}, Value};

                _ ->
                    invalid(Text)
            end end),
    gleam@result:unwrap(_pipe@3, invalid(Text)).

-file("src/molt/value.gleam", 1630).
-spec token_to_value(molt@types:toml_kind(), binary()) -> value().
token_to_value(Kind, Text) ->
    case Kind of
        bool_true ->
            {toml_bool, true};

        bool_false ->
            {toml_bool, false};

        inf ->
            {toml_infinity, unsigned};

        pos_inf ->
            {toml_infinity, positive};

        neg_inf ->
            {toml_infinity, negative};

        na_n ->
            {toml_na_n, unsigned};

        pos_na_n ->
            {toml_na_n, positive};

        neg_na_n ->
            {toml_na_n, negative};

        integer ->
            parse_base(Text, 10);

        hex_integer ->
            parse_base(Text, 16);

        octal_integer ->
            parse_base(Text, 8);

        binary_integer ->
            parse_base(Text, 2);

        float ->
            parse_float(Text);

        offset_date_time ->
            {toml_offset_date_time, Text};

        local_date_time ->
            {toml_local_date_time, Text};

        local_date ->
            {toml_local_date, Text};

        local_time ->
            {toml_local_time, Text};

        basic_string ->
            {toml_basic_string,
                {some, <<<<"\""/utf8, Text/binary>>/binary, "\""/utf8>>},
                molt@internal@utils:unescape_basic_string(Text)};

        multiline_basic_string ->
            {toml_multiline_basic_string,
                {some, <<<<"\"\"\""/utf8, Text/binary>>/binary, "\"\"\""/utf8>>},
                molt@internal@utils:unescape_basic_string(Text),
                false};

        multiline_basic_string_nl ->
            {toml_multiline_basic_string,
                {some,
                    <<<<"\"\"\"\n"/utf8, Text/binary>>/binary, "\"\"\""/utf8>>},
                molt@internal@utils:unescape_basic_string(Text),
                true};

        literal_string ->
            {toml_literal_string, Text};

        multiline_literal_string ->
            {toml_multiline_literal_string, Text, false};

        multiline_literal_string_nl ->
            {toml_multiline_literal_string, Text, true};

        invalid_value ->
            invalid(Text);

        _ ->
            invalid(Text)
    end.

-file("src/molt/value.gleam", 1698).
-spec inline_table_node_to_value(greenwood:node_(molt@types:toml_kind())) -> value().
inline_table_node_to_value(Node) ->
    _pipe = erlang:element(3, Node),
    _pipe@2 = gleam@list:filter_map(_pipe, fun(El) -> case El of
                {node_element, {node, key_value, _, _} = Kv} ->
                    Key = begin
                        _pipe@1 = molt@internal@cst@elements:key_name(
                            erlang:element(3, Kv)
                        ),
                        gleam@option:unwrap(_pipe@1, <<""/utf8>>)
                    end,
                    Val = case molt@internal@cst@elements:find_first_value(
                        molt@internal@cst@elements:value_tokens(
                            erlang:element(3, Kv)
                        )
                    ) of
                        {some, Val_el} ->
                            element_to_value(Val_el);

                        none ->
                            invalid(<<""/utf8>>)
                    end,
                    {ok, {Key, Val}};

                _ ->
                    {error, nil}
            end end),
    {toml_inline_table, _pipe@2}.

-file("src/molt/value.gleam", 1683).
-spec array_node_to_value(greenwood:node_(molt@types:toml_kind())) -> value().
array_node_to_value(Node) ->
    _pipe = erlang:element(3, Node),
    _pipe@1 = gleam@list:filter_map(_pipe, fun(El) -> case El of
                {node_element, {node, array_element, Children, _}} ->
                    case molt@internal@cst@elements:find_first_value(Children) of
                        {some, Val_el} ->
                            {ok, element_to_value(Val_el)};

                        none ->
                            {error, nil}
                    end;

                _ ->
                    {error, nil}
            end end),
    {toml_array, _pipe@1}.

-file("src/molt/value.gleam", 1675).
-spec node_to_value(greenwood:node_(molt@types:toml_kind())) -> value().
node_to_value(Node) ->
    case erlang:element(2, Node) of
        array ->
            array_node_to_value(Node);

        inline_table ->
            inline_table_node_to_value(Node);

        _ ->
            invalid(<<""/utf8>>)
    end.

-file("src/molt/value.gleam", 1623).
-spec element_to_value(greenwood:element(molt@types:toml_kind())) -> value().
element_to_value(Element) ->
    case Element of
        {token_element, {token, Kind, Text}} ->
            token_to_value(Kind, Text);

        {node_element, Node} ->
            node_to_value(Node)
    end.

-file("src/molt/value.gleam", 1331).
?DOC(false).
-spec from_cst(greenwood:node_(molt@types:toml_kind())) -> value().
from_cst(Kv) ->
    case erlang:element(2, Kv) of
        array_element ->
            _pipe = molt@internal@cst@elements:find_first_value(
                erlang:element(3, Kv)
            ),
            _pipe@1 = gleam@option:map(_pipe, fun element_to_value/1),
            gleam@option:unwrap(_pipe@1, invalid(<<""/utf8>>));

        _ ->
            _pipe@2 = molt@internal@cst@elements:find_first_value(
                molt@internal@cst@elements:value_tokens(erlang:element(3, Kv))
            ),
            _pipe@3 = gleam@option:map(_pipe@2, fun element_to_value/1),
            gleam@option:unwrap(_pipe@3, invalid(<<""/utf8>>))
    end.

-file("src/molt/value.gleam", 1287).
?DOC(
    " Parse a value as a Value or return an error if the value cannot be\n"
    " resolved.\n"
    "\n"
    " `constructor`\n"
).
-spec parse_value(binary()) -> {ok, value()} | {error, molt@error:molt_error()}.
parse_value(Text) ->
    Doc_text = <<<<"v = "/utf8, (gleam@string:trim(Text))/binary>>/binary,
        "\n"/utf8>>,
    gleam@result:'try'(
        begin
            _pipe = molt@internal@parser:parse(Doc_text),
            gleam@result:replace_error(_pipe, {value_parse_error, none, Text})
        end,
        fun(Root) -> case molt@cst:get(Root, [{key_segment, <<"v"/utf8>>}]) of
                {ok, Kv} ->
                    case from_cst(Kv) of
                        {toml_invalid, Text@1} ->
                            {error, {value_parse_error, none, Text@1}};

                        Value ->
                            {ok, Value}
                    end;

                {error, _} ->
                    {error, {value_parse_error, none, Text}}
            end end
    ).

-file("src/molt/value.gleam", 1307).
?DOC(false).
-spec from_table_entries(list({binary(), value()})) -> value().
from_table_entries(Entries) ->
    {toml_table, Entries}.

-file("src/molt/value.gleam", 1312).
?DOC(false).
-spec from_array_of_tables(list(value())) -> {ok, value()} |
    {error, molt@error:molt_error()}.
from_array_of_tables(Items) ->
    gleam@bool:guard(gleam@list:all(Items, fun(V) -> case V of
                    {toml_table, _} ->
                        true;

                    _ ->
                        false
                end end), {ok, {toml_array_of_tables, Items}}, fun() ->
            {error,
                {type_mismatch,
                    none,
                    <<"table"/utf8>>,
                    <<"non-table item in array table"/utf8>>}}
        end).