-module(molt@internal@document@primitives).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/molt/internal/document/primitives.gleam").
-export([patch/3, rebuild_kv_value/2, rebuild_array_element/2, cursor_replace_value/4, insert_kv_before_first_header/2, write_at_site/5, rebuild/2, find_kv_value/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/document/primitives.gleam", 23).
?DOC(false).
-spec patch(
molt@types:document(),
greenwood:node_(molt@types:toml_kind()),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry())
) -> molt@types:document().
patch(Doc, Tree, Idx) ->
{document,
erlang:element(2, Doc),
erlang:element(3, Doc),
Tree,
{some, Idx}}.
-file("src/molt/internal/document/primitives.gleam", 67).
?DOC(false).
-spec rebuild_kv_value(
greenwood:node_(molt@types:toml_kind()),
greenwood:element(molt@types:toml_kind())
) -> greenwood:node_(molt@types:toml_kind()).
rebuild_kv_value(Kv, New_value) ->
case molt@internal@cst@elements:split_at_equals(erlang:element(3, Kv)) of
{Prefix, [Eq | After_eq]} ->
{Ws, After_ws} = molt@internal@cst@elements:split_leading_ws(
After_eq
),
{Old_value, Trailing} = molt@internal@cst@elements:split_before_trivia(
After_ws
),
Trailing_ws = molt@internal@cst@elements:take_trailing_ws(Old_value),
{node,
erlang:element(2, Kv),
lists:append(
[Prefix, [Eq], Ws, [New_value], Trailing_ws, Trailing]
),
erlang:element(4, Kv)};
{_, []} ->
Kv
end.
-file("src/molt/internal/document/primitives.gleam", 57).
?DOC(false).
-spec rebuild_array_element(
greenwood:node_(molt@types:toml_kind()),
greenwood:element(molt@types:toml_kind())
) -> greenwood:node_(molt@types:toml_kind()).
rebuild_array_element(Element, New_value) ->
case erlang:element(3, Element) of
[_ | Trailing] ->
{node,
erlang:element(2, Element),
[New_value | Trailing],
erlang:element(4, Element)};
[] ->
{node,
erlang:element(2, Element),
[New_value],
erlang:element(4, Element)}
end.
-file("src/molt/internal/document/primitives.gleam", 32).
?DOC(false).
-spec cursor_replace_value(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
list(molt@types:path_segment()),
greenwood:element(molt@types:toml_kind())
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
cursor_replace_value(Doc, Idx, Segments, New_value) ->
Key = molt@internal@document@index:path_to_index_key(Segments),
{Container, _} = molt@internal@path:split_last_segment(Segments),
Entry = molt@internal@document@index:entry_for_element(New_value, Container),
Idx@1 = molt@internal@document@index:update_entry(Idx, Key, Entry),
gleam@result:'try'(
begin
_pipe = molt@internal@cst@query:get_cursor(
erlang:element(4, Doc),
Segments
),
gleam@result:replace_error(
_pipe,
molt@error:not_found_path(Segments)
)
end,
fun(Cursor) ->
New_node = case erlang:element(2, erlang:element(2, Cursor)) of
array_element ->
rebuild_array_element(erlang:element(2, Cursor), New_value);
_ ->
rebuild_kv_value(erlang:element(2, Cursor), New_value)
end,
_pipe@1 = greenwood@zipper:set_focus(Cursor, New_node),
_pipe@2 = greenwood@zipper:unzip(_pipe@1),
_pipe@3 = patch(Doc, _pipe@2, Idx@1),
{ok, _pipe@3}
end
).
-file("src/molt/internal/document/primitives.gleam", 290).
?DOC(false).
-spec insert_kv_into_inline_container(
greenwood:node_(molt@types:toml_kind()),
greenwood:element(molt@types:toml_kind())
) -> greenwood:node_(molt@types:toml_kind()).
insert_kv_into_inline_container(Container, Kv_el) ->
Children = lists:reverse(erlang:element(3, Container)),
New_children = case Children of
[{token_element, {token, right_brace, _}} = Rb | Rest] ->
lists:reverse(
[Rb,
Kv_el,
{token_element, {token, whitespace, <<" "/utf8>>}},
{token_element, {token, comma, <<""/utf8>>}} |
Rest]
);
_ ->
lists:append(erlang:element(3, Container), [Kv_el])
end,
{node,
erlang:element(2, Container),
New_children,
erlang:element(4, Container)}.
-file("src/molt/internal/document/primitives.gleam", 269).
?DOC(false).
-spec focus_inline_container(greenwood:zipper(molt@types:toml_kind())) -> {ok,
greenwood:zipper(molt@types:toml_kind())} |
{error, molt@error:molt_error()}.
focus_inline_container(Cursor) ->
case erlang:element(2, erlang:element(2, Cursor)) of
inline_table ->
{ok, Cursor};
key_value ->
_pipe = greenwood@zipper:down_where(
Cursor,
fun(N) -> erlang:element(2, N) =:= inline_table end
),
gleam@option:to_result(
_pipe,
{type_mismatch,
none,
<<"inline table"/utf8>>,
molt@internal@utils:toml_kind(
erlang:element(2, erlang:element(2, Cursor))
)}
);
Other ->
{error,
{type_mismatch,
none,
<<"inline table"/utf8>>,
molt@internal@utils:toml_kind(Other)}}
end.
-file("src/molt/internal/document/primitives.gleam", 232).
?DOC(false).
-spec write_new_inline_descend_missing(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
list(molt@types:path_segment()),
molt@value:value()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
write_new_inline_descend_missing(Doc, Idx, Full_path, Val) ->
{Container_path, Last} = molt@internal@path:split_last_segment(Full_path),
case Last of
{key_segment, Key} ->
gleam@result:'try'(
begin
_pipe = molt@internal@cst@query:get_cursor(
erlang:element(4, Doc),
Container_path
),
gleam@result:replace_error(
_pipe,
molt@error:not_found_path(Full_path)
)
end,
fun(Parent_cursor) ->
Kv_el = {node_element,
molt@internal@cst@builder:build_inline_kv(
molt@internal@utils:quote_key(Key),
molt@value:to_cst(Val)
)},
gleam@result:'try'(
focus_inline_container(Parent_cursor),
fun(Insert_cursor) ->
New_inline = insert_kv_into_inline_container(
erlang:element(2, Insert_cursor),
Kv_el
),
_pipe@1 = greenwood@zipper:set_focus(
Insert_cursor,
New_inline
),
_pipe@2 = greenwood@zipper:unzip(_pipe@1),
_pipe@3 = patch(Doc, _pipe@2, Idx),
{ok, _pipe@3}
end
)
end
);
_ ->
{error, molt@error:not_found_path(Full_path)}
end.
-file("src/molt/internal/document/primitives.gleam", 206).
?DOC(false).
-spec write_new_inline_descend(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
list(molt@types:path_segment()),
molt@value:value()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
write_new_inline_descend(Doc, Idx, Full_path, Val) ->
case molt@internal@cst@query:get_cursor(erlang:element(4, Doc), Full_path) of
{ok, Cursor} ->
New_node = case erlang:element(2, erlang:element(2, Cursor)) of
array_element ->
rebuild_array_element(
erlang:element(2, Cursor),
molt@value:to_cst(Val)
);
_ ->
rebuild_kv_value(
erlang:element(2, Cursor),
molt@value:to_cst(Val)
)
end,
_pipe = greenwood@zipper:set_focus(Cursor, New_node),
_pipe@1 = greenwood@zipper:unzip(_pipe),
_pipe@2 = patch(Doc, _pipe@1, Idx),
{ok, _pipe@2};
_ ->
write_new_inline_descend_missing(Doc, Idx, Full_path, Val)
end.
-file("src/molt/internal/document/primitives.gleam", 119).
?DOC(false).
-spec insert_kv_before_first_header(
greenwood:node_(molt@types:toml_kind()),
greenwood:node_(molt@types:toml_kind())
) -> greenwood:node_(molt@types:toml_kind()).
insert_kv_before_first_header(Tree, Kv) ->
Kv_el = {node_element, Kv},
{Before, After} = gleam@list:split_while(
erlang:element(3, Tree),
fun(El) -> case El of
{node_element, N} ->
(erlang:element(2, N) /= table) andalso (erlang:element(
2,
N
)
/= array_of_tables);
_ ->
true
end end
),
{node,
erlang:element(2, Tree),
lists:append([Before, [Kv_el], After]),
erlang:element(4, Tree)}.
-file("src/molt/internal/document/primitives.gleam", 188).
?DOC(false).
-spec write_new_root_dotted_key(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
list(molt@types:path_segment()),
molt@value:value()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
write_new_root_dotted_key(Doc, Idx, Full_path, Val) ->
Key_names = gleam@list:filter_map(Full_path, fun(Seg) -> case Seg of
{key_segment, Name} ->
{ok, molt@internal@utils:quote_key(Name)};
{index_segment, _} ->
{error, nil}
end end),
Kv = molt@internal@cst@builder:build_kv_from_path(
Key_names,
molt@value:to_cst(Val)
),
New_tree = insert_kv_before_first_header(erlang:element(4, Doc), Kv),
{ok, patch(Doc, New_tree, Idx)}.
-file("src/molt/internal/document/primitives.gleam", 157).
?DOC(false).
-spec write_new_concrete_append(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
list(molt@types:path_segment()),
molt@value:value(),
list(molt@types:path_segment())
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
write_new_concrete_append(Doc, Idx, Full_path, Val, Container_path) ->
Tail = gleam@list:drop(Full_path, erlang:length(Container_path)),
Key_names = gleam@list:filter_map(Tail, fun(Seg) -> case Seg of
{key_segment, Name} ->
{ok, molt@internal@utils:quote_key(Name)};
{index_segment, _} ->
{error, nil}
end end),
Kv = molt@internal@cst@builder:build_kv_from_path(
Key_names,
molt@value:to_cst(Val)
),
gleam@result:'try'(
begin
_pipe = molt@internal@cst@query:get_cursor(
erlang:element(4, Doc),
Container_path
),
gleam@result:replace_error(
_pipe,
molt@error:not_found_path(Container_path)
)
end,
fun(Cursor) ->
_pipe@1 = greenwood@zipper:map_focus(
Cursor,
fun(_capture) ->
greenwood:append_child(_capture, {node_element, Kv})
end
),
_pipe@2 = greenwood@zipper:unzip(_pipe@1),
_pipe@3 = patch(Doc, _pipe@2, Idx),
{ok, _pipe@3}
end
).
-file("src/molt/internal/document/primitives.gleam", 138).
?DOC(false).
-spec do_write_new(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
list(molt@types:path_segment()),
molt@value:value(),
molt@internal@document@index:insertion_site()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
do_write_new(Doc, Idx, Full_path, Val, Site) ->
case Site of
{concrete_append, Container_path} ->
write_new_concrete_append(Doc, Idx, Full_path, Val, Container_path);
{root_dotted_key, Full_path@1} ->
write_new_root_dotted_key(Doc, Idx, Full_path@1, Val);
{inline_descend, Full_path@2} ->
write_new_inline_descend(Doc, Idx, Full_path@2, Val)
end.
-file("src/molt/internal/document/primitives.gleam", 94).
?DOC(false).
-spec write_at_site(
molt@types:document(),
gleam@dict:dict(molt@types:index_key(), molt@types:index_entry()),
molt@internal@document@index:insertion_site(),
list(molt@types:path_segment()),
molt@value:value()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
write_at_site(Doc, Idx, Site, Full_path, Val) ->
Idx_key = molt@internal@document@index:path_to_index_key(Full_path),
Container = case Site of
{root_dotted_key, _} ->
[];
{concrete_append, Container_path} ->
Container_path;
{inline_descend, _} ->
erlang:element(1, molt@internal@path:split_last_segment(Full_path))
end,
Entry = molt@internal@document@index:entry_for_value(Val, Container),
Idx@1 = molt@internal@document@index:ensure_implicit_tables(Idx, Full_path),
Idx@2 = molt@internal@document@index:insert_entry(Idx@1, Idx_key, Entry),
do_write_new(Doc, Idx@2, Full_path, Val, Site).
-file("src/molt/internal/document/primitives.gleam", 313).
?DOC(false).
-spec rebuild(molt@types:document(), greenwood:node_(molt@types:toml_kind())) -> molt@types:document().
rebuild(Doc, Tree) ->
{document,
erlang:element(2, Doc),
erlang:element(3, Doc),
Tree,
begin
_pipe = molt@internal@document@index:build_tree_index(Tree),
{some, _pipe}
end}.
-file("src/molt/internal/document/primitives.gleam", 319).
?DOC(false).
-spec find_kv_value(
greenwood:node_(molt@types:toml_kind()),
molt@types:toml_kind()
) -> {ok, greenwood:node_(molt@types:toml_kind())} | {error, nil}.
find_kv_value(Kv, Kind) ->
gleam@list:find_map(erlang:element(3, Kv), fun(El) -> case El of
{node_element, N} when erlang:element(2, N) =:= Kind ->
{ok, N};
_ ->
{error, nil}
end end).