Skip to main content

src/molt@internal@cst@query.erl

-module(molt@internal@cst@query).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/molt/internal/cst/query.gleam").
-export([collect_key_prefix/1, get_cursor_where/3, get_cursor/2, get/2]).

-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).

-file("src/molt/internal/cst/query.gleam", 459).
?DOC(false).
-spec is_kv_named(greenwood:node_(molt@types:toml_kind()), binary()) -> boolean().
is_kv_named(Node, Key) ->
    (erlang:element(2, Node) =:= key_value) andalso (molt@internal@cst@elements:key_name(
        erlang:element(3, Node)
    )
    =:= {some, Key}).

-file("src/molt/internal/cst/query.gleam", 490).
?DOC(false).
-spec is_table_at(greenwood:node_(molt@types:toml_kind()), list(binary())) -> boolean().
is_table_at(Node, Path) ->
    ((erlang:element(2, Node) =:= table) orelse (erlang:element(2, Node) =:= array_of_tables))
    andalso (molt@internal@cst@elements:extract_key_segments(
        erlang:element(3, Node)
    )
    =:= Path).

-file("src/molt/internal/cst/query.gleam", 468).
?DOC(false).
-spec kv_key_segments(list(greenwood:element(molt@types:toml_kind()))) -> list(binary()).
kv_key_segments(Children) ->
    case Children of
        [] ->
            [];

        [{token_element, {token, equals, _}} | _] ->
            [];

        [{node_element, N} | _] when erlang:element(2, N) =:= key ->
            molt@internal@cst@elements:extract_key_segments(
                erlang:element(3, N)
            );

        [{token_element, {token, bare_key, Text}} | Rest] ->
            [Text | kv_key_segments(Rest)];

        [{token_element, {token, basic_string, Text@1}} | Rest@1] ->
            [molt@internal@utils:unescape_basic_string(Text@1) |
                kv_key_segments(Rest@1)];

        [{token_element, {token, literal_string, Text@2}} | Rest@2] ->
            [Text@2 | kv_key_segments(Rest@2)];

        [_ | Rest@3] ->
            kv_key_segments(Rest@3)
    end.

-file("src/molt/internal/cst/query.gleam", 463).
?DOC(false).
-spec is_kv_with_path(greenwood:node_(molt@types:toml_kind()), list(binary())) -> boolean().
is_kv_with_path(Node, Path) ->
    (erlang:element(2, Node) =:= key_value) andalso (kv_key_segments(
        erlang:element(3, Node)
    )
    =:= Path).

-file("src/molt/internal/cst/query.gleam", 411).
?DOC(false).
-spec try_shorter_table_prefix(
    greenwood:zipper(molt@types:toml_kind()),
    list(binary()),
    list(binary()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} | {error, list(binary())}.
try_shorter_table_prefix(Cursor, Prefix, Full_prefix, Filter) ->
    case gleam@list:take(Prefix, erlang:length(Prefix) - 1) of
        [] ->
            {error, []};

        Init ->
            case greenwood@zipper:down_where(
                Cursor,
                fun(_capture) -> is_table_at(_capture, Init) end
            ) of
                {some, Inner_cursor} ->
                    Rest = gleam@list:drop(Full_prefix, erlang:length(Init)),
                    case resolve_over_key(Inner_cursor, Rest, Filter) of
                        {ok, Cursor@1} ->
                            {ok, Cursor@1};

                        {error, _} ->
                            {error, Init}
                    end;

                none ->
                    try_shorter_table_prefix(Cursor, Init, Full_prefix, Filter)
            end
    end.

-file("src/molt/internal/cst/query.gleam", 329).
?DOC(false).
-spec resolve_over_key(
    greenwood:zipper(molt@types:toml_kind()),
    list(binary()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} | {error, list(binary())}.
resolve_over_key(Cursor, Prefix, Filter) ->
    case greenwood@zipper:down_where(
        Cursor,
        fun(N) -> is_table_at(N, Prefix) andalso Filter(N) end
    ) of
        {some, Cursor@1} ->
            {ok, Cursor@1};

        none ->
            case Prefix of
                [] ->
                    {error, []};

                [Key] ->
                    _pipe = greenwood@zipper:down_where(
                        Cursor,
                        fun(N@1) ->
                            is_kv_named(N@1, Key) andalso Filter(N@1)
                        end
                    ),
                    gleam@option:to_result(_pipe, []);

                _ ->
                    case greenwood@zipper:down_where(
                        Cursor,
                        fun(N@2) ->
                            is_kv_with_path(N@2, Prefix) andalso Filter(N@2)
                        end
                    ) of
                        {some, Cursor@2} ->
                            {ok, Cursor@2};

                        none ->
                            try_shorter_table_prefix(
                                Cursor,
                                Prefix,
                                Prefix,
                                Filter
                            )
                    end
            end
    end.

-file("src/molt/internal/cst/query.gleam", 495).
?DOC(false).
-spec is_array_of_tables_at(
    greenwood:node_(molt@types:toml_kind()),
    list(binary())
) -> boolean().
is_array_of_tables_at(Node, Path) ->
    (erlang:element(2, Node) =:= array_of_tables) andalso (molt@internal@cst@elements:extract_key_segments(
        erlang:element(3, Node)
    )
    =:= Path).

-file("src/molt/internal/cst/query.gleam", 41).
?DOC(false).
-spec collect_key_prefix(list(molt@types:path_segment())) -> list(binary()).
collect_key_prefix(Path) ->
    case Path of
        [{key_segment, K} | Rest] ->
            [K | collect_key_prefix(Rest)];

        _ ->
            []
    end.

-file("src/molt/internal/cst/query.gleam", 600).
?DOC(false).
-spec count_right_matches(
    greenwood:zipper(molt@types:toml_kind()),
    list(binary())
) -> integer().
count_right_matches(Cursor, Segments) ->
    case greenwood@zipper:right_where(
        Cursor,
        fun(_capture) -> is_array_of_tables_at(_capture, Segments) end
    ) of
        {some, Cursor@1} ->
            1 + count_right_matches(Cursor@1, Segments);

        none ->
            0
    end.

-file("src/molt/internal/cst/query.gleam", 500).
?DOC(false).
-spec resolve_to_nth_match(
    greenwood:zipper(molt@types:toml_kind()),
    integer(),
    list(binary())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} | {error, nil}.
resolve_to_nth_match(Cursor, Index, Segments) ->
    Count = count_right_matches(Cursor, Segments) + 1,
    Resolved = molt@internal@utils:resolve_index(Index, Count),
    case Resolved of
        0 ->
            {ok, Cursor};

        N when N > 0 ->
            _pipe = greenwood@zipper:right_n_where(
                Cursor,
                N,
                fun(_capture) -> is_array_of_tables_at(_capture, Segments) end
            ),
            gleam@option:to_result(_pipe, nil);

        _ ->
            {error, nil}
    end.

-file("src/molt/internal/cst/query.gleam", 438).
?DOC(false).
-spec resolve_into_array_of_tables(
    greenwood:zipper(molt@types:toml_kind()),
    list(binary()),
    integer()
) -> {ok, greenwood:zipper(molt@types:toml_kind())} | {error, nil}.
resolve_into_array_of_tables(Cursor, Prefix, Index) ->
    case greenwood@zipper:down_where(
        Cursor,
        fun(_capture) -> is_array_of_tables_at(_capture, Prefix) end
    ) of
        {some, Cursor@1} ->
            resolve_to_nth_match(Cursor@1, Index, Prefix);

        none ->
            case Prefix of
                [Key | Rest] when Rest =/= [] ->
                    gleam@result:'try'(
                        begin
                            _pipe = greenwood@zipper:down_where(
                                Cursor,
                                fun(_capture@1) ->
                                    is_table_at(_capture@1, [Key])
                                end
                            ),
                            gleam@option:to_result(_pipe, nil)
                        end,
                        fun(Cursor@2) ->
                            resolve_into_array_of_tables(Cursor@2, Rest, Index)
                        end
                    );

                _ ->
                    {error, nil}
            end
    end.

-file("src/molt/internal/cst/query.gleam", 163).
?DOC(false).
-spec resolve_into_array_element_value(greenwood:zipper(molt@types:toml_kind())) -> {ok,
        greenwood:zipper(molt@types:toml_kind())} |
    {error, nil}.
resolve_into_array_element_value(Cursor) ->
    _pipe = greenwood@zipper:down_where(
        Cursor,
        fun(N) ->
            (erlang:element(2, N) =:= inline_table) orelse (erlang:element(2, N)
            =:= array)
        end
    ),
    gleam@option:to_result(_pipe, nil).

-file("src/molt/internal/cst/query.gleam", 152).
?DOC(false).
-spec resolve_into_kv_value(greenwood:zipper(molt@types:toml_kind())) -> {ok,
        greenwood:zipper(molt@types:toml_kind())} |
    {error, nil}.
resolve_into_kv_value(Cursor) ->
    _pipe = greenwood@zipper:down_where(
        Cursor,
        fun(N) ->
            (erlang:element(2, N) =:= array) orelse (erlang:element(2, N) =:= inline_table)
        end
    ),
    gleam@option:to_result(_pipe, nil).

-file("src/molt/internal/cst/query.gleam", 586).
?DOC(false).
-spec is_array_element(greenwood:node_(molt@types:toml_kind())) -> boolean().
is_array_element(N) ->
    erlang:element(2, N) =:= array_element.

-file("src/molt/internal/cst/query.gleam", 590).
?DOC(false).
-spec is_node(
    greenwood:element(molt@types:toml_kind()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> boolean().
is_node(El, Predicate) ->
    case El of
        {node_element, N} ->
            Predicate(N);

        _ ->
            false
    end.

-file("src/molt/internal/cst/query.gleam", 173).
?DOC(false).
-spec resolve_into_nth_array_element(
    greenwood:zipper(molt@types:toml_kind()),
    integer()
) -> {ok, greenwood:zipper(molt@types:toml_kind())} | {error, nil}.
resolve_into_nth_array_element(Cursor, Index) ->
    case greenwood@zipper:down_where(Cursor, fun is_array_element/1) of
        none ->
            {error, nil};

        {some, Child_cursor} ->
            Count = gleam@list:count(
                erlang:element(3, erlang:element(2, Cursor)),
                fun(_capture) -> is_node(_capture, fun is_array_element/1) end
            ),
            Offset = molt@internal@utils:resolve_index(Index, Count),
            gleam@bool:guard(
                Offset < 0,
                {error, nil},
                fun() ->
                    _pipe = greenwood@zipper:right_n_where(
                        Child_cursor,
                        Offset,
                        fun is_array_element/1
                    ),
                    gleam@option:to_result(_pipe, nil)
                end
            )
    end.

-file("src/molt/internal/cst/query.gleam", 368).
?DOC(false).
-spec resolve_under_key(
    greenwood:zipper(molt@types:toml_kind()),
    list(molt@types:path_segment()),
    list(binary()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    list(binary()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_under_key(
    Cursor,
    After,
    Prefix,
    Segments,
    Visited,
    Resolved_prefix,
    Predicate
) ->
    case Prefix of
        [First_key | Rest_keys] ->
            case greenwood@zipper:down_where(
                Cursor,
                fun(_capture) -> is_kv_named(_capture, First_key) end
            ) of
                {some, Kv_cursor} ->
                    Rest_path = lists:append(
                        gleam@list:map(
                            Rest_keys,
                            fun(Field@0) -> {key_segment, Field@0} end
                        ),
                        After
                    ),
                    Kv_visited = [{key_segment, First_key} | Visited],
                    resolve_path(Kv_cursor, Rest_path, Kv_visited, Predicate);

                none ->
                    Visited@1 = lists:append(
                        lists:reverse(
                            gleam@list:map(
                                Resolved_prefix,
                                fun(Field@0) -> {key_segment, Field@0} end
                            )
                        ),
                        Visited
                    ),
                    {error, molt@error:not_found_path2(Segments, Visited@1)}
            end;

        _ ->
            Visited@2 = lists:append(
                lists:reverse(
                    gleam@list:map(
                        Resolved_prefix,
                        fun(Field@0) -> {key_segment, Field@0} end
                    )
                ),
                Visited
            ),
            {error, molt@error:not_found_path2(Segments, Visited@2)}
    end.

-file("src/molt/internal/cst/query.gleam", 529).
?DOC(false).
-spec resolve_aot_scoped_path(
    greenwood:zipper(molt@types:toml_kind()),
    list(binary()),
    list(binary()),
    list(binary()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_aot_scoped_path(
    Cursor,
    Aot_prefix,
    Sub_prefix,
    Full_sub_prefix,
    After,
    Segments,
    Visited,
    Predicate
) ->
    case Sub_prefix of
        [] ->
            {error, molt@error:not_found_path2(Segments, Visited)};

        _ ->
            Full_table_path = lists:append(Aot_prefix, Sub_prefix),
            Remaining = lists:append(
                gleam@list:map(
                    gleam@list:drop(Full_sub_prefix, erlang:length(Sub_prefix)),
                    fun(Field@0) -> {key_segment, Field@0} end
                ),
                After
            ),
            Filter = case Remaining of
                [] ->
                    Predicate;

                _ ->
                    fun(_) -> true end
            end,
            Stop = fun(_capture) ->
                is_array_of_tables_at(_capture, Aot_prefix)
            end,
            case greenwood@zipper:right_until(
                Cursor,
                fun(N) -> is_table_at(N, Full_table_path) andalso Filter(N) end,
                Stop
            ) of
                {some, Sub_cursor} ->
                    resolve_path(Sub_cursor, Remaining, Visited, Predicate);

                none ->
                    resolve_aot_scoped_path(
                        Cursor,
                        Aot_prefix,
                        gleam@list:take(
                            Sub_prefix,
                            erlang:length(Sub_prefix) - 1
                        ),
                        Full_sub_prefix,
                        After,
                        Segments,
                        Visited,
                        Predicate
                    )
            end
    end.

-file("src/molt/internal/cst/query.gleam", 281).
?DOC(false).
-spec resolve_into_index_after_key(
    greenwood:zipper(molt@types:toml_kind()),
    integer(),
    list(binary()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_into_index_after_key(
    Cursor,
    Index,
    Prefix,
    Segments,
    Rest,
    Visited,
    New_visited,
    Predicate
) ->
    case resolve_into_array_of_tables(Cursor, Prefix, Index) of
        {ok, Found} ->
            Sub_prefix = collect_key_prefix(Rest),
            After = gleam@list:drop(Rest, erlang:length(Sub_prefix)),
            _pipe = resolve_path(Found, Rest, New_visited, Predicate),
            gleam@result:lazy_or(
                _pipe,
                fun() ->
                    resolve_aot_scoped_path(
                        Found,
                        Prefix,
                        Sub_prefix,
                        Sub_prefix,
                        After,
                        Segments,
                        New_visited,
                        Predicate
                    )
                end
            );

        {error, nil} ->
            case Prefix of
                [Key] ->
                    case greenwood@zipper:down_where(
                        Cursor,
                        fun(_capture) -> is_kv_named(_capture, Key) end
                    ) of
                        {some, Kv_cursor} ->
                            resolve_path(
                                Kv_cursor,
                                [{index_segment, Index} | Rest],
                                [{key_segment, Key} | Visited],
                                Predicate
                            );

                        none ->
                            {error,
                                molt@error:not_found_path2(Segments, Visited)}
                    end;

                _ ->
                    {error, molt@error:not_found_path2(Segments, Visited)}
            end
    end.

-file("src/molt/internal/cst/query.gleam", 226).
?DOC(false).
-spec resolve_into_key(
    greenwood:zipper(molt@types:toml_kind()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_into_key(Cursor, Segments, Visited, Predicate) ->
    Prefix = collect_key_prefix(Segments),
    After = gleam@list:drop(Segments, erlang:length(Prefix)),
    New_visited = lists:append(
        lists:reverse(
            gleam@list:map(Prefix, fun(Field@0) -> {key_segment, Field@0} end)
        ),
        Visited
    ),
    case After of
        [{index_segment, Index} | Rest] ->
            resolve_into_index_after_key(
                Cursor,
                Index,
                Prefix,
                Segments,
                Rest,
                Visited,
                New_visited,
                Predicate
            );

        _ ->
            Filter = case After =:= [] of
                true ->
                    Predicate;

                false ->
                    fun(_) -> true end
            end,
            case resolve_over_key(Cursor, Prefix, Filter) of
                {ok, Found} ->
                    resolve_path(Found, After, New_visited, Predicate);

                {error, Resolved_prefix} ->
                    resolve_under_key(
                        Cursor,
                        After,
                        Prefix,
                        Segments,
                        Visited,
                        Resolved_prefix,
                        Predicate
                    )
            end
    end.

-file("src/molt/internal/cst/query.gleam", 197).
?DOC(false).
-spec resolve_into_inline_table(
    greenwood:zipper(molt@types:toml_kind()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_into_inline_table(Cursor, Segments, Visited, Predicate) ->
    case Segments of
        [] ->
            {ok, Cursor};

        [{key_segment, Key} | Rest] ->
            gleam@result:'try'(
                begin
                    _pipe = greenwood@zipper:down_where(
                        Cursor,
                        fun(_capture) -> is_kv_named(_capture, Key) end
                    ),
                    gleam@option:to_result(
                        _pipe,
                        molt@error:not_found_path3(Segments, Rest, Visited)
                    )
                end,
                fun(Cursor@1) -> case Rest of
                        [] ->
                            gleam@bool:guard(
                                Predicate(erlang:element(2, Cursor@1)),
                                {ok, Cursor@1},
                                fun() ->
                                    {error,
                                        molt@error:not_found_path2(
                                            Segments,
                                            Visited
                                        )}
                                end
                            );

                        _ ->
                            Visited@1 = [{key_segment, Key} | Visited],
                            resolve_path(Cursor@1, Rest, Visited@1, Predicate)
                    end end
            );

        _ ->
            {error, molt@error:not_found_path2(Segments, Visited)}
    end.

-file("src/molt/internal/cst/query.gleam", 118).
?DOC(false).
-spec resolve_path_by_key(
    greenwood:zipper(molt@types:toml_kind()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_path_by_key(Cursor, Segments, Visited, Predicate) ->
    case erlang:element(2, erlang:element(2, Cursor)) of
        inline_table ->
            resolve_into_inline_table(Cursor, Segments, Visited, Predicate);

        key_value ->
            gleam@result:'try'(
                begin
                    _pipe = resolve_into_kv_value(Cursor),
                    gleam@result:replace_error(
                        _pipe,
                        molt@error:not_found_path2(Segments, Visited)
                    )
                end,
                fun(Cursor@1) ->
                    resolve_path(Cursor@1, Segments, Visited, Predicate)
                end
            );

        array_element ->
            gleam@result:'try'(
                begin
                    _pipe@1 = resolve_into_array_element_value(Cursor),
                    gleam@result:replace_error(
                        _pipe@1,
                        molt@error:not_found_path2(Segments, Visited)
                    )
                end,
                fun(Cursor@2) ->
                    resolve_path(Cursor@2, Segments, Visited, Predicate)
                end
            );

        _ ->
            resolve_into_key(Cursor, Segments, Visited, Predicate)
    end.

-file("src/molt/internal/cst/query.gleam", 72).
?DOC(false).
-spec resolve_path_by_index(
    greenwood:zipper(molt@types:toml_kind()),
    integer(),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_path_by_index(Cursor, Index, Segments, Rest, Visited, Predicate) ->
    case erlang:element(2, erlang:element(2, Cursor)) of
        array ->
            gleam@result:'try'(
                begin
                    _pipe = resolve_into_nth_array_element(Cursor, Index),
                    gleam@result:replace_error(
                        _pipe,
                        molt@error:not_found_path3(Segments, Rest, Visited)
                    )
                end,
                fun(Cursor@1) ->
                    resolve_path(
                        Cursor@1,
                        Rest,
                        [{index_segment, Index} | Visited],
                        Predicate
                    )
                end
            );

        key_value ->
            gleam@result:'try'(
                begin
                    _pipe@1 = resolve_into_kv_value(Cursor),
                    gleam@result:replace_error(
                        _pipe@1,
                        molt@error:not_found_path3(Segments, Rest, Visited)
                    )
                end,
                fun(Cursor@2) ->
                    resolve_path(Cursor@2, Segments, Visited, Predicate)
                end
            );

        array_element ->
            gleam@result:'try'(
                begin
                    _pipe@2 = resolve_into_array_element_value(Cursor),
                    gleam@result:replace_error(
                        _pipe@2,
                        molt@error:not_found_path3(Segments, Rest, Visited)
                    )
                end,
                fun(Cursor@3) ->
                    resolve_path(Cursor@3, Segments, Visited, Predicate)
                end
            );

        _ ->
            {error, molt@error:not_found_path2(Segments, Visited)}
    end.

-file("src/molt/internal/cst/query.gleam", 48).
?DOC(false).
-spec resolve_path(
    greenwood:zipper(molt@types:toml_kind()),
    list(molt@types:path_segment()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
resolve_path(Cursor, Segments, Visited, Predicate) ->
    case Segments of
        [] ->
            {ok, Cursor};

        [{index_segment, Index} | Rest] ->
            resolve_path_by_index(
                Cursor,
                Index,
                Segments,
                Rest,
                Visited,
                Predicate
            );

        [{key_segment, _} | _] ->
            resolve_path_by_key(Cursor, Segments, Visited, Predicate)
    end.

-file("src/molt/internal/cst/query.gleam", 30).
?DOC(false).
-spec get_cursor_where(
    greenwood:node_(molt@types:toml_kind()),
    list(molt@types:path_segment()),
    fun((greenwood:node_(molt@types:toml_kind())) -> boolean())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
get_cursor_where(Node, Segments, Predicate) ->
    _pipe = Node,
    _pipe@1 = greenwood@zipper:zip(_pipe),
    resolve_path(_pipe@1, Segments, [], Predicate).

-file("src/molt/internal/cst/query.gleam", 23).
?DOC(false).
-spec get_cursor(
    greenwood:node_(molt@types:toml_kind()),
    list(molt@types:path_segment())
) -> {ok, greenwood:zipper(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
get_cursor(Node, Segments) ->
    get_cursor_where(Node, Segments, fun(_) -> true end).

-file("src/molt/internal/cst/query.gleam", 15).
?DOC(false).
-spec get(
    greenwood:node_(molt@types:toml_kind()),
    list(molt@types:path_segment())
) -> {ok, greenwood:node_(molt@types:toml_kind())} |
    {error, molt@error:molt_error()}.
get(Node, Segments) ->
    _pipe = get_cursor(Node, Segments),
    gleam@result:map(_pipe, fun(Cursor) -> erlang:element(2, Cursor) end).