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