Skip to main content

src/yum@yaml@parser@double_quoted.erl

-module(yum@yaml@parser@double_quoted).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/yum/yaml/parser/double_quoted.gleam").
-export([fold_scalar/2, parser/0]).
-export_type([double_quoted_element/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(false).

-type double_quoted_element() :: {raw, binary()} |
    {escaped, binary()} |
    escaped_line_break.

-file("src/yum/yaml/parser/double_quoted.gleam", 93).
?DOC(false).
-spec next_is_escaped_line_break(list(double_quoted_element())) -> boolean().
next_is_escaped_line_break(Elements) ->
    case Elements of
        [escaped_line_break | _] ->
            true;

        _ ->
            false
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 188).
?DOC(false).
-spec starts_with_whitespace(binary()) -> boolean().
starts_with_whitespace(S) ->
    case S of
        <<" "/utf8, _/binary>> ->
            true;

        <<"\t"/utf8, _/binary>> ->
            true;

        <<"\r"/utf8, _/binary>> ->
            true;

        <<"\n"/utf8, _/binary>> ->
            true;

        _ ->
            false
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 235).
?DOC(false).
-spec trailing_whitespace(binary(), integer(), integer()) -> {integer(),
    boolean()}.
trailing_whitespace(S, Content_length, Pending_whitespace) ->
    case S of
        <<""/utf8>> ->
            {Content_length, Pending_whitespace > 0};

        <<" "/utf8, Rest/binary>> ->
            trailing_whitespace(Rest, Content_length, Pending_whitespace + 1);

        <<"\t"/utf8, Rest/binary>> ->
            trailing_whitespace(Rest, Content_length, Pending_whitespace + 1);

        <<"\r"/utf8, Rest/binary>> ->
            trailing_whitespace(Rest, Content_length, Pending_whitespace + 1);

        <<"\n"/utf8, Rest/binary>> ->
            trailing_whitespace(Rest, Content_length, Pending_whitespace + 1);

        _ ->
            Rest@2 = case gleam_stdlib:string_pop_grapheme(S) of
                {ok, {_, Rest@1}} -> Rest@1;
                _assert_fail ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"yum/yaml/parser/double_quoted"/utf8>>,
                                function => <<"trailing_whitespace"/utf8>>,
                                line => 247,
                                value => _assert_fail,
                                start => 6845,
                                'end' => 6895,
                                pattern_start => 6856,
                                pattern_end => 6870})
            end,
            trailing_whitespace(
                Rest@2,
                (Content_length + Pending_whitespace) + 1,
                0
            )
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 226).
?DOC(false).
-spec drop_trailing_whitespace(binary()) -> {binary(), boolean()}.
drop_trailing_whitespace(S) ->
    {Content_length, Has_trailing_whitespace} = trailing_whitespace(S, 0, 0),
    case Has_trailing_whitespace of
        true ->
            {gleam@string:slice(S, 0, Content_length), true};

        false ->
            {S, false}
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 210).
?DOC(false).
-spec drop_leading_whitespace(binary()) -> binary().
drop_leading_whitespace(S) ->
    case S of
        <<" "/utf8, Rest/binary>> ->
            drop_leading_whitespace(Rest);

        <<"\t"/utf8, Rest/binary>> ->
            drop_leading_whitespace(Rest);

        <<"\r"/utf8, Rest/binary>> ->
            drop_leading_whitespace(Rest);

        <<"\n"/utf8, Rest/binary>> ->
            drop_leading_whitespace(Rest);

        _ ->
            S
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 197).
?DOC(false).
-spec trim_whitespace(binary()) -> {binary(), boolean()}.
trim_whitespace(S) ->
    Without_leading = drop_leading_whitespace(S),
    {Without_trailing, Has_trailing_whitespace} = drop_trailing_whitespace(
        Without_leading
    ),
    {Without_trailing,
        (gleam@string:is_empty(S) orelse (not gleam@string:is_empty(S) andalso gleam@string:is_empty(
            Without_leading
        )))
        orelse Has_trailing_whitespace}.

-file("src/yum/yaml/parser/double_quoted.gleam", 148).
?DOC(false).
-spec fold_flow_lines_loop(list(binary()), list(binary()), integer(), boolean()) -> {list(binary()),
    boolean()}.
fold_flow_lines_loop(Lines, Parts, Empty_lines, Ends_with_whitespace) ->
    case Lines of
        [] ->
            {Parts, Ends_with_whitespace};

        [Line | Rest] ->
            {Line@1, Ends_with_whitespace@1} = trim_whitespace(Line),
            case {gleam@string:is_empty(Line@1), Parts} of
                {true, _} ->
                    fold_flow_lines_loop(
                        Rest,
                        Parts,
                        Empty_lines + 1,
                        Ends_with_whitespace@1
                    );

                {false, []} ->
                    fold_flow_lines_loop(
                        Rest,
                        [Line@1],
                        0,
                        Ends_with_whitespace@1
                    );

                {false, [_ | _]} ->
                    Separator = case Empty_lines > 0 of
                        true ->
                            gleam@string:repeat(<<"\n"/utf8>>, Empty_lines);

                        false ->
                            <<" "/utf8>>
                    end,
                    fold_flow_lines_loop(
                        Rest,
                        [Line@1, Separator | Parts],
                        0,
                        Ends_with_whitespace@1
                    )
            end
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 137).
?DOC(false).
-spec fold_flow_lines(list(binary())) -> {binary(), boolean()}.
fold_flow_lines(Lines) ->
    {Parts, Ends_with_whitespace} = fold_flow_lines_loop(Lines, [], 0, false),
    {begin
            _pipe = Parts,
            _pipe@1 = lists:reverse(_pipe),
            erlang:list_to_binary(_pipe@1)
        end,
        Ends_with_whitespace}.

-file("src/yum/yaml/parser/double_quoted.gleam", 218).
?DOC(false).
-spec split_trailing_whitespace(binary()) -> {binary(), binary()}.
split_trailing_whitespace(S) ->
    {Content_length, _} = trailing_whitespace(S, 0, 0),
    {gleam@string:slice(S, 0, Content_length),
        gleam@string:drop_start(S, Content_length)}.

-file("src/yum/yaml/parser/double_quoted.gleam", 104).
?DOC(false).
-spec fold_scalar(binary(), boolean()) -> binary().
fold_scalar(Scalar, Preserve_trailing_whitespace) ->
    gleam@bool:guard(
        Scalar =:= <<""/utf8>>,
        <<""/utf8>>,
        fun() ->
            gleam@bool:guard(
                not gleam_stdlib:contains_string(Scalar, <<"\n"/utf8>>),
                Scalar,
                fun() ->
                    {Scalar@1, Preserved_trailing_whitespace} = case Preserve_trailing_whitespace of
                        true ->
                            split_trailing_whitespace(Scalar);

                        false ->
                            {Scalar, <<""/utf8>>}
                    end,
                    {Trimmed, Ends_with_whitespace} = begin
                        _pipe = Scalar@1,
                        _pipe@1 = gleam@string:split(_pipe, <<"\n"/utf8>>),
                        fold_flow_lines(_pipe@1)
                    end,
                    Lead_padded = case starts_with_whitespace(Scalar@1) of
                        true ->
                            <<" "/utf8, Trimmed/binary>>;

                        false ->
                            Trimmed
                    end,
                    End_padded = case {Preserve_trailing_whitespace,
                        Ends_with_whitespace} of
                        {true, _} ->
                            Lead_padded;

                        {false, true} ->
                            <<Lead_padded/binary, " "/utf8>>;

                        {false, false} ->
                            Lead_padded
                    end,
                    <<End_padded/binary, Preserved_trailing_whitespace/binary>>
                end
            )
        end
    ).

-file("src/yum/yaml/parser/double_quoted.gleam", 79).
?DOC(false).
-spec strip_double_escaped_prefix(binary(), list(double_quoted_element())) -> {binary(),
    boolean()}.
strip_double_escaped_prefix(Value, Rest) ->
    Stripped = drop_leading_whitespace(Value),
    case {gleam@string:is_empty(Stripped), Rest} of
        {true, [{escaped, _} | _]} ->
            {Stripped, false};

        {true, []} ->
            {Stripped, false};

        {true, _} ->
            {Stripped, true};

        {false, _} ->
            {Stripped, false}
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 50).
?DOC(false).
-spec render_elements_loop(
    list(double_quoted_element()),
    boolean(),
    list(binary())
) -> list(binary()).
render_elements_loop(Elements, Strip_prefix, Parts) ->
    case Elements of
        [] ->
            Parts;

        [{raw, Value} | Rest] ->
            {Value@1, Strip_prefix@1} = case Strip_prefix of
                true ->
                    strip_double_escaped_prefix(Value, Rest);

                false ->
                    {Value, false}
            end,
            render_elements_loop(
                Rest,
                Strip_prefix@1,
                [fold_scalar(Value@1, next_is_escaped_line_break(Rest)) | Parts]
            );

        [{escaped, Value@2} | Rest@1] ->
            render_elements_loop(Rest@1, false, [Value@2 | Parts]);

        [escaped_line_break | Rest@2] ->
            render_elements_loop(Rest@2, true, Parts)
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 44).
?DOC(false).
-spec render_elements(list(double_quoted_element())) -> binary().
render_elements(Elements) ->
    _pipe = render_elements_loop(Elements, false, []),
    _pipe@1 = lists:reverse(_pipe),
    erlang:list_to_binary(_pipe@1).

-file("src/yum/yaml/parser/double_quoted.gleam", 310).
?DOC(false).
-spec decode_codepoint(binary(), integer()) -> gleam@option:option(double_quoted_element()).
decode_codepoint(Hex_digits, Nof_digits) ->
    gleam@option:from_result(
        begin
            gleam@result:'try'(
                gleam_stdlib:base16_decode(Hex_digits),
                fun(Bits) ->
                    Size = Nof_digits * 4,
                    case Bits of
                        <<Codepoint:Size/integer>> ->
                            _pipe = Codepoint,
                            _pipe@1 = gleam@string:utf_codepoint(_pipe),
                            _pipe@2 = gleam@result:map(
                                _pipe@1,
                                fun gleam@list:wrap/1
                            ),
                            _pipe@3 = gleam@result:map(
                                _pipe@2,
                                fun gleam_stdlib:utf_codepoint_list_to_string/1
                            ),
                            gleam@result:map(
                                _pipe@3,
                                fun(Field@0) -> {escaped, Field@0} end
                            );

                        _ ->
                            {error, nil}
                    end
                end
            )
        end
    ).

-file("src/yum/yaml/parser/double_quoted.gleam", 254).
?DOC(false).
-spec parse_escape(binary()) -> gleam@option:option(double_quoted_element()).
parse_escape(S) ->
    case S of
        <<"0"/utf8>> ->
            {some, {escaped, <<"\x{00}"/utf8>>}};

        <<"a"/utf8>> ->
            {some, {escaped, <<"\x{07}"/utf8>>}};

        <<"b"/utf8>> ->
            {some, {escaped, <<"\x{08}"/utf8>>}};

        <<"t"/utf8>> ->
            {some, {escaped, <<"\x{09}"/utf8>>}};

        <<"n"/utf8>> ->
            {some, {escaped, <<"\x{0A}"/utf8>>}};

        <<"v"/utf8>> ->
            {some, {escaped, <<"\x{0B}"/utf8>>}};

        <<"f"/utf8>> ->
            {some, {escaped, <<"\x{0C}"/utf8>>}};

        <<"r"/utf8>> ->
            {some, {escaped, <<"\x{0D}"/utf8>>}};

        <<"e"/utf8>> ->
            {some, {escaped, <<"\x{1B}"/utf8>>}};

        <<" "/utf8>> ->
            {some, {escaped, <<"\x{20}"/utf8>>}};

        <<"\""/utf8>> ->
            {some, {escaped, <<"\x{22}"/utf8>>}};

        <<"/"/utf8>> ->
            {some, {escaped, <<"\x{2F}"/utf8>>}};

        <<"\\"/utf8>> ->
            {some, {escaped, <<"\x{5C}"/utf8>>}};

        <<"N"/utf8>> ->
            {some, {escaped, <<"\x{85}"/utf8>>}};

        <<"_"/utf8>> ->
            {some, {escaped, <<"\x{A0}"/utf8>>}};

        <<"L"/utf8>> ->
            {some, {escaped, <<"\x{2028}"/utf8>>}};

        <<"P"/utf8>> ->
            {some, {escaped, <<"\x{2029}"/utf8>>}};

        <<"x"/utf8, Ns_hex_digit_2/binary>> ->
            decode_codepoint(Ns_hex_digit_2, 2);

        <<"u"/utf8, Ns_hex_digit_4/binary>> ->
            decode_codepoint(Ns_hex_digit_4, 4);

        <<"U"/utf8, Ns_hex_digit_8/binary>> ->
            decode_codepoint(Ns_hex_digit_8, 8);

        <<"\n"/utf8>> ->
            {some, escaped_line_break};

        _ ->
            none
    end.

-file("src/yum/yaml/parser/double_quoted.gleam", 21).
?DOC(false).
-spec parser() -> nibble:parser(yum@yaml@node:node_(), yum@yaml@token:token(), yum@yaml@lexer@context:context()).
parser() ->
    nibble:do(
        nibble:token(double_quote),
        fun(_) ->
            nibble:do(
                nibble:span(),
                fun(Start) ->
                    nibble:do(
                        nibble:many(
                            begin
                                nibble:take_map(
                                    <<"Expected a double quoted value"/utf8>>,
                                    fun(Token) -> case Token of
                                            {double_quoted_scalar, Value} ->
                                                {some, {raw, Value}};

                                            {escape, Value@1} ->
                                                parse_escape(Value@1);

                                            _ ->
                                                none
                                        end end
                                )
                            end
                        ),
                        fun(Elements) ->
                            nibble:do(
                                nibble:token(double_quote),
                                fun(_) ->
                                    nibble:do(
                                        nibble:span(),
                                        fun(End) -> _pipe = Elements,
                                            _pipe@1 = render_elements(_pipe),
                                            _pipe@2 = {string, _pipe@1},
                                            _pipe@3 = yum@yaml@node:new(
                                                _pipe@2,
                                                yum@yaml@parser@span:between(
                                                    Start,
                                                    End
                                                ),
                                                double_quoted_scalar
                                            ),
                                            nibble:return(_pipe@3) end
                                    )
                                end
                            )
                        end
                    )
                end
            )
        end
    ).