src/molt@internal@document@representation.erl
-module(molt@internal@document@representation).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/molt/internal/document/representation.gleam").
-export([set_representation/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/representation.gleam", 379).
?DOC(false).
-spec has_comment({list(binary()), gleam@option:option(binary())}) -> boolean().
has_comment(Comments) ->
{Leading, Trailing} = Comments,
(Leading /= []) orelse (Trailing /= none).
-file("src/molt/internal/document/representation.gleam", 97).
?DOC(false).
-spec do_indices(integer(), list(integer())) -> list(integer()).
do_indices(I, Acc) ->
gleam@bool:guard(I < 0, Acc, fun() -> do_indices(I - 1, [I | Acc]) end).
-file("src/molt/internal/document/representation.gleam", 93).
?DOC(false).
-spec indices_up_to(integer()) -> list(integer()).
indices_up_to(N) ->
do_indices(N - 1, []).
-file("src/molt/internal/document/representation.gleam", 180).
?DOC(false).
-spec capture_entry_comments(
greenwood:node_(molt@types:toml_kind()),
list(molt@types:path_segment()),
integer()
) -> {ok, list({list(binary()), gleam@option:option(binary())})} |
{error, molt@error:molt_error()}.
capture_entry_comments(Tree, Segments, Count) ->
gleam@list:try_map(
indices_up_to(Count),
fun(I) ->
Entry_path = lists:append(Segments, [{index_segment, I}]),
gleam@result:'try'(
molt@cst:leading_comments(Tree, Entry_path),
fun(Leading) ->
gleam@result:'try'(
molt@cst:trailing_comment(Tree, Entry_path),
fun(Trailing) -> {ok, {Leading, Trailing}} end
)
end
)
end
).
-file("src/molt/internal/document/representation.gleam", 331).
?DOC(false).
-spec aot_to_inline_array(
molt@types:document(),
list(molt@types:path_segment()),
integer()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
aot_to_inline_array(Doc, Segments, Count) ->
Indices = indices_up_to(Count),
gleam@result:'try'(
gleam@list:try_map(
Indices,
fun(I) ->
Entry_path = lists:append(Segments, [{index_segment, I}]),
gleam@result:'try'(
molt@cst:get(erlang:element(4, Doc), Entry_path),
fun(Entry) ->
Kvs = molt@internal@cst@elements:get_kv_children(
erlang:element(3, Entry)
),
{ok,
molt@internal@cst@elements:section_kvs_to_inline_table(
Kvs
)}
end
)
end
),
fun(Inline_tables) ->
gleam@result:'try'(
capture_entry_comments(erlang:element(4, Doc), Segments, Count),
fun(Entry_comments) ->
Array_node = case gleam@list:any(
Entry_comments,
fun has_comment/1
) of
false ->
molt@internal@cst@elements:inline_tables_to_array(
Inline_tables
);
true ->
molt@internal@cst@elements:inline_tables_to_multiline_array(
Inline_tables,
Entry_comments
)
end,
{Parent, Last} = molt@internal@path:split_last_segment(
Segments
),
Key = case Last of
{key_segment, K} ->
K;
{index_segment, _} ->
<<""/utf8>>
end,
Kv = molt@internal@cst@builder:build_kv_node(
Key,
{node_element, Array_node}
),
gleam@result:'try'(
gleam@list:try_fold(
lists:reverse(Indices),
erlang:element(4, Doc),
fun(Tree, I@1) ->
molt@cst:delete(
Tree,
lists:append(
Segments,
[{index_segment, I@1}]
)
)
end
),
fun(Deleted) ->
gleam@result:'try'(
molt@cst:insert_kv(
Deleted,
Parent,
Kv,
kv_at_end
),
fun(New_tree) ->
{ok,
molt@internal@document@primitives:rebuild(
Doc,
New_tree
)}
end
)
end
)
end
)
end
).
-file("src/molt/internal/document/representation.gleam", 201).
?DOC(false).
-spec block_table_to_inline(
molt@types:document(),
list(molt@types:path_segment())
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
block_table_to_inline(Doc, Segments) ->
gleam@result:'try'(
molt@cst:get(erlang:element(4, Doc), Segments),
fun(Table_node) ->
Kvs = molt@internal@cst@elements:get_kv_children(
erlang:element(3, Table_node)
),
Inline = molt@internal@cst@elements:section_kvs_to_inline_table(Kvs),
{Parent, Last} = molt@internal@path:split_last_segment(Segments),
Key = case Last of
{key_segment, K} ->
K;
{index_segment, _} ->
<<""/utf8>>
end,
Base_kv = molt@internal@cst@builder:build_kv_node(
Key,
{node_element, Inline}
),
Kv = begin
_pipe = {node,
erlang:element(2, Base_kv),
erlang:element(3, Base_kv),
erlang:element(4, Table_node)},
molt@internal@cst@builder:drop_leading_newlines(_pipe)
end,
gleam@result:'try'(
molt@cst:delete(erlang:element(4, Doc), Segments),
fun(Deleted) ->
gleam@result:'try'(
molt@cst:insert_kv(Deleted, Parent, Kv, kv_at_end),
fun(New_tree) ->
{ok,
molt@internal@document@primitives:rebuild(
Doc,
New_tree
)}
end
)
end
)
end
).
-file("src/molt/internal/document/representation.gleam", 157).
?DOC(false).
-spec set_comments_if_any(
greenwood:node_(molt@types:toml_kind()),
list(molt@types:path_segment()),
list(binary()),
gleam@option:option(binary())
) -> {ok, greenwood:node_(molt@types:toml_kind())} |
{error, molt@error:molt_error()}.
set_comments_if_any(Tree, Segments, Leading, Trailing) ->
gleam@result:'try'(case Leading of
[] ->
{ok, Tree};
_ ->
molt@cst:set_leading_comments(Tree, Segments, Leading)
end, fun(With_leading) -> case Trailing of
none ->
{ok, With_leading};
{some, _} ->
molt@cst:set_trailing_comment(
With_leading,
Segments,
Trailing
)
end end).
-file("src/molt/internal/document/representation.gleam", 317).
?DOC(false).
-spec build_aot_entry_from_inline(
list(binary()),
greenwood:node_(molt@types:toml_kind())
) -> greenwood:node_(molt@types:toml_kind()).
build_aot_entry_from_inline(Key_only, Inline_table) ->
Section_kvs = begin
_pipe = molt@internal@cst@elements:extract_inline_entries(Inline_table),
gleam@list:map(
_pipe,
fun molt@internal@cst@elements:kv_to_section_form/1
)
end,
Base = molt@internal@cst@builder:build_empty_array_of_tables(Key_only),
{node,
erlang:element(2, Base),
lists:append(
erlang:element(3, Base),
gleam@list:map(
Section_kvs,
fun(Field@0) -> {node_element, Field@0} end
)
),
erlang:element(4, Base)}.
-file("src/molt/internal/document/representation.gleam", 384).
?DOC(false).
-spec type_mismatch(list(molt@types:path_segment()), binary()) -> molt@error:molt_error().
type_mismatch(Segments, Expected) ->
{type_mismatch,
{some, molt@internal@path:to_string(Segments)},
Expected,
<<"value"/utf8>>}.
-file("src/molt/internal/document/representation.gleam", 304).
?DOC(false).
-spec element_inline_table(greenwood:node_(molt@types:toml_kind())) -> {ok,
greenwood:node_(molt@types:toml_kind())} |
{error, nil}.
element_inline_table(Elem) ->
gleam@list:find_map(erlang:element(3, Elem), fun(Child) -> case Child of
{node_element, N} when erlang:element(2, N) =:= inline_table ->
{ok, N};
_ ->
{error, nil}
end end).
-file("src/molt/internal/document/representation.gleam", 232).
?DOC(false).
-spec inline_array_to_block_aot(
molt@types:document(),
list(molt@types:path_segment())
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
inline_array_to_block_aot(Doc, Segments) ->
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) ->
gleam@result:'try'(
begin
_pipe@1 = molt@internal@document@primitives:find_kv_value(
erlang:element(2, Cursor),
array
),
gleam@result:replace_error(
_pipe@1,
type_mismatch(Segments, <<"array"/utf8>>)
)
end,
fun(Array_node) ->
gleam@result:'try'(
gleam@list:try_map(
molt@internal@cst@elements:extract_array_items(
Array_node
),
fun(Elem) -> _pipe@2 = element_inline_table(Elem),
gleam@result:replace_error(
_pipe@2,
type_mismatch(
Segments,
<<"array of inline tables"/utf8>>
)
) end
),
fun(Inline_tables) ->
gleam@result:'try'(
molt@cst:leading_comments(
erlang:element(4, Doc),
Segments
),
fun(Whole_leading) ->
gleam@result:'try'(
molt@cst:trailing_comment(
erlang:element(4, Doc),
Segments
),
fun(Whole_trailing) ->
Count = erlang:length(Inline_tables),
gleam@result:'try'(
capture_entry_comments(
erlang:element(4, Doc),
Segments,
Count
),
fun(Element_comments) ->
Key_only = molt@internal@path:path_to_table_header(
Segments
),
Entries = gleam@list:map(
Inline_tables,
fun(It) ->
build_aot_entry_from_inline(
Key_only,
It
)
end
),
gleam@result:'try'(
molt@cst:delete(
erlang:element(
4,
Doc
),
Segments
),
fun(Deleted) ->
gleam@result:'try'(
gleam@list:try_fold(
Entries,
Deleted,
fun(
Tree,
Entry
) ->
molt@cst:insert_table_node(
Tree,
Entry
)
end
),
fun(Inserted) ->
gleam@result:'try'(
gleam@list:try_fold(
gleam@list:index_map(
Element_comments,
fun(
C,
I
) ->
{I,
C}
end
),
Inserted,
fun(
Tree@1,
Indexed
) ->
{I@1,
{Elem_leading,
Elem_trailing}} = Indexed,
Leading = case I@1 of
0 ->
lists:append(
Whole_leading,
Elem_leading
);
_ ->
Elem_leading
end,
Trailing = case {I@1,
Elem_trailing} of
{0,
none} ->
Whole_trailing;
{_,
T} ->
T
end,
set_comments_if_any(
Tree@1,
lists:append(
Segments,
[{index_segment,
I@1}]
),
Leading,
Trailing
)
end
),
fun(
New_tree
) ->
{ok,
molt@internal@document@primitives:rebuild(
Doc,
New_tree
)}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/molt/internal/document/representation.gleam", 104).
?DOC(false).
-spec inline_table_to_block(
molt@types:document(),
list(molt@types:path_segment())
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
inline_table_to_block(Doc, Segments) ->
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) ->
gleam@result:'try'(
begin
_pipe@1 = molt@internal@document@primitives:find_kv_value(
erlang:element(2, Cursor),
inline_table
),
gleam@result:replace_error(
_pipe@1,
{type_mismatch,
{some, molt@internal@path:to_string(Segments)},
<<"inline table"/utf8>>,
molt@internal@utils:toml_kind(
erlang:element(2, erlang:element(2, Cursor))
)}
)
end,
fun(Inline_table) ->
Section_kvs = begin
_pipe@2 = molt@internal@cst@elements:extract_inline_entries(
Inline_table
),
gleam@list:map(
_pipe@2,
fun molt@internal@cst@elements:kv_to_section_form/1
)
end,
gleam@result:'try'(
molt@cst:leading_comments(
erlang:element(4, Doc),
Segments
),
fun(Leading) ->
gleam@result:'try'(
molt@cst:trailing_comment(
erlang:element(4, Doc),
Segments
),
fun(Trailing) ->
molt@internal@document@index:with_index(
Doc,
fun(Idx) ->
gleam@result:'try'(
molt@internal@document@remove:prune(
Doc,
Idx,
Segments
),
fun(Doc2) ->
Key_only = molt@internal@path:path_to_table_header(
Segments
),
Header = molt@internal@cst@builder:build_empty_table(
Key_only
),
gleam@result:'try'(
molt@cst:insert_table_node(
erlang:element(
4,
Doc2
),
Header
),
fun(With_header) ->
Section_cst_path = gleam@list:map(
Key_only,
fun(Field@0) -> {key_segment, Field@0} end
),
gleam@result:'try'(
gleam@list:try_fold(
Section_kvs,
With_header,
fun(
Tree,
Kv
) ->
molt@cst:insert_kv(
Tree,
Section_cst_path,
Kv,
kv_at_end
)
end
),
fun(Filled) ->
gleam@result:'try'(
set_comments_if_any(
Filled,
Segments,
Leading,
Trailing
),
fun(
New_tree
) ->
{ok,
molt@internal@document@primitives:rebuild(
Doc2,
New_tree
)}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/molt/internal/document/representation.gleam", 48).
?DOC(false).
-spec convert(
molt@types:document(),
binary(),
list(molt@types:path_segment()),
molt@ops:form()
) -> {ok, molt@types:document()} | {error, molt@error:molt_error()}.
convert(Doc, P, Segments, Form) ->
molt@internal@document@index:with_index(
Doc,
fun(Idx) ->
case {Form, molt@internal@document@index:resolve(Idx, Segments)} of
{block, {hit, _, {index_inline_table_value, _}}} ->
inline_table_to_block(Doc, Segments);
{block, {hit, _, {index_table, _}}} ->
{ok, Doc};
{block, {hit, _, {index_array_of_tables, _, _}}} ->
{ok, Doc};
{block, {hit, _, {index_array_value, _}}} ->
inline_array_to_block_aot(Doc, Segments);
{inline, {hit, _, {index_table, _}}} ->
block_table_to_inline(Doc, Segments);
{inline, {hit, _, {index_array_of_tables, Count, _}}} ->
aot_to_inline_array(Doc, Segments, Count);
{inline, {hit, _, {index_inline_table_value, _}}} ->
{ok, Doc};
{_, {hit, _, Entry}} ->
{error,
{type_mismatch,
{some, P},
<<"inline or block table / array of tables"/utf8>>,
molt@internal@utils:index_entry_to_string(Entry)}};
{_, {miss, _, _, _}} ->
{error, molt@error:not_found(P)};
{_, {fresh, _}} ->
{error, molt@error:not_found(P)}
end
end
).
-file("src/molt/internal/document/representation.gleam", 27).
?DOC(false).
-spec set_representation(molt@types:document(), binary(), molt@ops:form()) -> {ok,
molt@types:document()} |
{error, molt@error:molt_error()}.
set_representation(Doc, P, Form) ->
gleam@result:'try'(
molt@internal@path:parse(P),
fun(Segments) ->
gleam@result:'try'(
convert(Doc, P, Segments, Form),
fun(Converted) ->
case molt@internal@validate:count(
erlang:element(4, Converted)
) of
0 ->
{ok, Converted};
_ ->
{error,
{invalid_operation,
<<"representation"/utf8>>,
{some,
<<<<"conversion would produce invalid TOML at \""/utf8,
P/binary>>/binary,
"\""/utf8>>}}}
end
end
)
end
).