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