-module(molt@internal@document).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/molt/internal/document.gleam").
-export([run/2, list_keys/2, get_value/3, get_value_at/3]).
-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/document.gleam", 27).
?DOC(false).
-spec run(molt@types:document(), molt@ops:operation()) -> {ok,
molt@types:document()} |
{error, molt@error:molt_error()}.
run(Doc, Op) ->
case Op of
{set, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"set"/utf8>>, none}};
{set, P, Value} ->
molt@internal@document@values:set(Doc, P, Value);
{remove, <<""/utf8>>} ->
{error, {invalid_operation, <<"remove"/utf8>>, none}};
{remove, P@1} ->
molt@internal@document@remove:delete(Doc, P@1);
{move, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"move"/utf8>>, none}};
{move, _, <<""/utf8>>} ->
{error, {invalid_operation, <<"move"/utf8>>, none}};
{move, From, To} ->
molt@internal@document@reshape:move(Doc, From, To);
{rename, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"rename"/utf8>>, none}};
{rename, P@2, To@1} ->
molt@internal@document@reshape:rename(Doc, P@2, To@1);
{ensure_exists, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"ensure_exists"/utf8>>, none}};
{ensure_exists, P@3, Kind} ->
molt@internal@document@structure:ensure_exists(Doc, P@3, Kind);
{merge_values, <<""/utf8>>, _, _} ->
{error, {invalid_operation, <<"merge_values"/utf8>>, none}};
{merge_values, P@4, Entries, On_conflict} ->
molt@internal@document@structure:merge_values(
Doc,
P@4,
Entries,
On_conflict
);
{move_keys, From@1, To@2, Keys, On_conflict@1} ->
molt@internal@document@reshape:move_keys(
Doc,
From@1,
To@2,
Keys,
On_conflict@1
);
{transfer, From@2, To@3, On_conflict@2} ->
molt@internal@document@reshape:merge(
Doc,
From@2,
To@3,
On_conflict@2
);
{append, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"append"/utf8>>, none}};
{append, P@5, Value@1} ->
molt@internal@document@arrays:append(Doc, P@5, Value@1);
{concat, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"concat"/utf8>>, none}};
{concat, P@6, Values} ->
molt@internal@document@arrays:concat(Doc, P@6, Values);
{insert, <<""/utf8>>, _, _} ->
{error, {invalid_operation, <<"insert"/utf8>>, none}};
{insert, P@7, Before, Value@2} ->
molt@internal@document@arrays:insert(Doc, P@7, Before, Value@2);
{insert_key, P@8, Before@1, Key, Value@3} ->
molt@internal@document@values:insert_key(
Doc,
P@8,
Before@1,
Key,
Value@3
);
{update, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"update"/utf8>>, none}};
{update, P@9, With} ->
molt@internal@document@values:update(Doc, P@9, With);
{representation, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"representation"/utf8>>, none}};
{representation, P@10, Form} ->
molt@internal@document@representation:set_representation(
Doc,
P@10,
Form
);
{move_comments, From@3, To@4} ->
molt@internal@document@comments:move_comments(Doc, From@3, To@4);
{set_comments, P@11, Comments} ->
molt@internal@document@comments:set_comments(Doc, P@11, Comments);
{place, <<""/utf8>>, _} ->
{error, {invalid_operation, <<"place"/utf8>>, none}};
{place, P@12, Value@4} ->
molt@internal@document@values:replace(Doc, P@12, Value@4)
end.
-file("src/molt/internal/document.gleam", 95).
?DOC(false).
-spec list_keys(molt@types:document(), list(molt@types:path_segment())) -> {ok,
list(binary())} |
{error, molt@error:molt_error()}.
list_keys(Doc, Path) ->
gleam@result:'try'(
molt@internal@document@index:get_index(Doc),
fun(Index) -> case Path of
[] ->
{ok, molt@internal@document@index:root_children(Index)};
_ ->
case molt@internal@document@index:get_path(Index, Path) of
{ok, {index_table, Children}} ->
{ok, Children};
{ok, {index_implicit_table, Children}} ->
{ok, Children};
{ok, {index_array_of_tables_entry, _, _, Children}} ->
{ok, Children};
{ok, {index_array_of_tables, _, _}} ->
{error,
{type_mismatch,
{some, molt@internal@path:to_string(Path)},
<<"a table entry (use an index to select an entry)"/utf8>>,
<<"array of tables"/utf8>>}};
{ok, _} ->
{error,
{type_mismatch,
{some, molt@internal@path:to_string(Path)},
<<"a table"/utf8>>,
<<"a value"/utf8>>}};
{error, nil} ->
{error, molt@error:not_found_path(Path)}
end
end end
).
-file("src/molt/internal/document.gleam", 250).
?DOC(false).
-spec is_array_of_tables_with_prefix(
greenwood:node_(molt@types:toml_kind()),
list(binary())
) -> boolean().
is_array_of_tables_with_prefix(Node, Prefix) ->
(erlang:element(2, Node) =:= array_of_tables) andalso (molt@internal@cst@elements:extract_key_segments(
erlang:element(3, Node)
)
=:= Prefix).
-file("src/molt/internal/document.gleam", 193).
?DOC(false).
-spec navigate_flat(
greenwood:zipper(molt@types:toml_kind()),
list(molt@types:path_segment()),
list(binary()),
boolean(),
gleam@option:option(list(binary()))
) -> gleam@option:option(greenwood:zipper(molt@types:toml_kind())).
navigate_flat(Cursor, Path, Prefix, First, Boundary) ->
Stop = case Boundary of
none ->
fun(_) -> false end;
{some, B} ->
fun(_capture) -> is_array_of_tables_with_prefix(_capture, B) end
end,
case Path of
[] ->
greenwood@zipper:right_until(
Cursor,
fun(Node) ->
((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)
)
=:= Prefix)
end,
Stop
);
[{key_segment, K} | Rest] ->
navigate_flat(
Cursor,
Rest,
lists:append(Prefix, [K]),
First,
Boundary
);
[{index_segment, N} | Rest@1] ->
Pred = fun(_capture@1) ->
is_array_of_tables_with_prefix(_capture@1, Prefix)
end,
Cursor@1 = case First of
true ->
_pipe = greenwood@zipper:down_where(Cursor, Pred),
gleam@option:then(
_pipe,
fun(_capture@2) ->
greenwood@zipper:right_n_until(
_capture@2,
N,
Pred,
Stop
)
end
);
false ->
_pipe@1 = greenwood@zipper:right_until(Cursor, Pred, Stop),
gleam@option:then(
_pipe@1,
fun(_capture@3) ->
greenwood@zipper:right_n_until(
_capture@3,
N,
Pred,
Stop
)
end
)
end,
gleam@option:then(Cursor@1, fun(Cursor@2) -> case Rest@1 of
[] ->
{some, Cursor@2};
_ ->
navigate_flat(
Cursor@2,
Rest@1,
Prefix,
false,
{some, Prefix}
)
end end)
end.
-file("src/molt/internal/document.gleam", 171).
?DOC(false).
-spec find_container_indexed(
greenwood:node_(molt@types:toml_kind()),
list(molt@types:path_segment())
) -> {ok, greenwood:node_(molt@types:toml_kind())} | {error, nil}.
find_container_indexed(Tree, Path) ->
_pipe = navigate_flat(greenwood@zipper:zip(Tree), Path, [], true, none),
_pipe@1 = gleam@option:map(_pipe, fun(C) -> erlang:element(2, C) end),
gleam@option:to_result(_pipe@1, nil).
-file("src/molt/internal/document.gleam", 272).
?DOC(false).
-spec has_index_segment(list(molt@types:path_segment())) -> boolean().
has_index_segment(Path) ->
gleam@list:any(Path, fun(S) -> case S of
{index_segment, _} ->
true;
_ ->
false
end end).
-file("src/molt/internal/document.gleam", 152).
?DOC(false).
-spec find_container(molt@types:document(), list(molt@types:path_segment())) -> {ok,
greenwood:node_(molt@types:toml_kind())} |
{error, molt@error:molt_error()}.
find_container(Doc, Segments) ->
gleam@bool:guard(
Segments =:= [],
{ok, erlang:element(4, Doc)},
fun() ->
gleam@bool:lazy_guard(
has_index_segment(Segments),
fun() ->
_pipe = find_container_indexed(
erlang:element(4, Doc),
Segments
),
gleam@result:replace_error(
_pipe,
molt@error:not_found_path(Segments)
)
end,
fun() ->
_pipe@1 = molt@cst:get(erlang:element(4, Doc), Segments),
gleam@result:replace_error(
_pipe@1,
molt@error:not_found_path(Segments)
)
end
)
end
).
-file("src/molt/internal/document.gleam", 259).
?DOC(false).
-spec require_key(
molt@types:document(),
list(molt@types:path_segment()),
binary()
) -> {ok, greenwood:node_(molt@types:toml_kind())} |
{error, molt@error:molt_error()}.
require_key(Doc, Segments, Key) ->
gleam@result:'try'(
find_container(Doc, Segments),
fun(Table_node) ->
_pipe = molt@cst:get(Table_node, [{key_segment, Key}]),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = lists:append(Segments, [{key_segment, Key}]),
molt@error:not_found_path(_pipe@1)
end
)
end
).
-file("src/molt/internal/document.gleam", 124).
?DOC(false).
-spec get_value(
molt@types:document(),
list(molt@types:path_segment()),
binary()
) -> {ok, molt@value:value()} | {error, molt@error:molt_error()}.
get_value(Doc, Path, Key) ->
gleam@result:'try'(
require_key(Doc, Path, Key),
fun(Kv_node) -> {ok, molt@value:from_cst(Kv_node)} end
).
-file("src/molt/internal/document.gleam", 136).
?DOC(false).
-spec get_value_at(
molt@types:document(),
list(molt@types:path_segment()),
list(molt@types:path_segment())
) -> {ok, molt@value:value()} | {error, molt@error:molt_error()}.
get_value_at(Doc, Container, Kv_key) ->
Full_path = lists:append(Container, Kv_key),
gleam@result:'try'(
find_container(Doc, Container),
fun(Container_node) ->
gleam@result:'try'(
begin
_pipe = molt@cst:get(Container_node, Kv_key),
gleam@result:replace_error(
_pipe,
molt@error:not_found_path(Full_path)
)
end,
fun(Kv_node) -> {ok, molt@value:from_cst(Kv_node)} end
)
end
).