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