-module(molt@internal@validate).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/molt/internal/validate.gleam").
-export([count/1, enrich/1]).
-export_type([path_entry/0, value_kind/0, pos/0, collector/1, state/1]).
-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).
-type path_entry() :: {explicit_table, molt@types:span()} |
{explicit_array_of_tables, integer(), molt@types:span()} |
{header_implicit, molt@types:span()} |
{dotted_implicit, molt@types:span()} |
{closed_implicit, molt@types:span()} |
{explicit_scalar, molt@types:span()} |
{explicit_inline_table, molt@types:span()} |
{explicit_inline_array, molt@types:span()}.
-type value_kind() :: scalar_value | inline_table_value | inline_array_value.
-type pos() :: {pos, integer(), integer(), integer()}.
-type collector(INE) :: {collector,
INE,
boolean(),
fun((INE, fun(() -> molt@types:syntax_error())) -> INE)}.
-type state(INF) :: {state,
collector(INF),
INF,
pos(),
list(binary()),
list(list(binary())),
gleam@dict:dict(list(binary()), path_entry()),
gleam@dict:dict(list(binary()), integer()),
integer()}.
-file("src/molt/internal/validate.gleam", 292).
?DOC(false).
-spec pop_path(state(IOD)) -> state(IOD).
pop_path(State) ->
case erlang:element(6, State) of
[Parent | Rest] ->
{state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
Parent,
Rest,
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State)};
[] ->
State
end.
-file("src/molt/internal/validate.gleam", 272).
?DOC(false).
-spec exit_node(state(INV), greenwood:node_(molt@types:toml_kind())) -> state(INV).
exit_node(State, Node) ->
gleam@bool:guard(
erlang:element(2, Node) =:= root,
State,
fun() ->
gleam@bool:guard(
erlang:element(2, Node) =:= error,
{state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State) - 1},
fun() ->
State@1 = case erlang:element(2, Node) of
array ->
{state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State) - 1};
inline_table ->
{state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State) - 1};
_ ->
State
end,
pop_path(State@1)
end
)
end
).
-file("src/molt/internal/validate.gleam", 288).
?DOC(false).
-spec push_path(state(INZ), list(binary())) -> state(INZ).
push_path(State, New_path) ->
{state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
New_path,
[erlang:element(5, State) | erlang:element(6, State)],
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State)}.
-file("src/molt/internal/validate.gleam", 388).
?DOC(false).
-spec pos_span(pos()) -> molt@types:span().
pos_span(Pos) ->
{span,
erlang:element(2, Pos),
erlang:element(3, Pos),
erlang:element(4, Pos)}.
-file("src/molt/internal/validate.gleam", 380).
?DOC(false).
-spec make_error(state(any()), molt@types:syntax_error_kind(), list(binary())) -> molt@types:syntax_error().
make_error(State, Kind, Path) ->
{syntax_error, Kind, Path, pos_span(erlang:element(4, State))}.
-file("src/molt/internal/validate.gleam", 190).
?DOC(false).
-spec emit(state(INO), fun(() -> molt@types:syntax_error())) -> state(INO).
emit(State, Build) ->
{state,
erlang:element(2, State),
(erlang:element(4, erlang:element(2, State)))(
erlang:element(3, State),
Build
),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State)}.
-file("src/molt/internal/validate.gleam", 724).
?DOC(false).
-spec push_error(state(IQS), molt@types:syntax_error_kind(), list(binary())) -> state(IQS).
push_error(State, Kind, Path) ->
emit(State, fun() -> make_error(State, Kind, Path) end).
-file("src/molt/internal/validate.gleam", 1039).
?DOC(false).
-spec do_inline_commas_ok(
list(greenwood:element(molt@types:toml_kind())),
boolean()
) -> boolean().
do_inline_commas_ok(Children, Seen_entry) ->
case Children of
[] ->
true;
[{token_element, {token, left_brace, _}} | Rest] ->
do_inline_commas_ok(Rest, false);
[{token_element, {token, right_brace, _}} | Rest@1] ->
do_inline_commas_ok(Rest@1, false);
[{token_element, {token, comma, _}} | Rest@2] ->
case Seen_entry of
true ->
do_inline_commas_ok(Rest@2, false);
false ->
false
end;
[{token_element, {token, whitespace, _}} | Rest@3] ->
do_inline_commas_ok(Rest@3, Seen_entry);
[{token_element, {token, newline, _}} | Rest@3] ->
do_inline_commas_ok(Rest@3, Seen_entry);
[{token_element, {token, comment, _}} | Rest@3] ->
do_inline_commas_ok(Rest@3, Seen_entry);
[_ | Rest@4] ->
do_inline_commas_ok(Rest@4, true)
end.
-file("src/molt/internal/validate.gleam", 1035).
?DOC(false).
-spec inline_table_commas_ok(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
inline_table_commas_ok(Children) ->
do_inline_commas_ok(Children, false).
-file("src/molt/internal/validate.gleam", 1066).
?DOC(false).
-spec do_inline_bare_ok(
list(greenwood:element(molt@types:toml_kind())),
boolean()
) -> boolean().
do_inline_bare_ok(Children, After_eq) ->
case Children of
[] ->
true;
[{token_element, {token, equals, _}} | Rest] ->
do_inline_bare_ok(Rest, true);
[{token_element, {token, comma, _}} | Rest@1] ->
do_inline_bare_ok(Rest@1, false);
[{token_element, {token, invalid_value, _}} | _] ->
false;
[{token_element, {token, invalid_basic_string, _}} | _] ->
false;
[{token_element, {token, invalid_literal_string, _}} | _] ->
false;
[{token_element, {token, invalid_multiline_basic_string, _}} | _] ->
false;
[{token_element, {token, invalid_multiline_literal_string, _}} | _] ->
false;
[{token_element, {token, bare_key, _}} | _] when After_eq ->
false;
[_ | Rest@2] ->
do_inline_bare_ok(Rest@2, After_eq)
end.
-file("src/molt/internal/validate.gleam", 1062).
?DOC(false).
-spec inline_table_bare_values_ok(
list(greenwood:element(molt@types:toml_kind()))
) -> boolean().
inline_table_bare_values_ok(Children) ->
do_inline_bare_ok(Children, false).
-file("src/molt/internal/validate.gleam", 392).
?DOC(false).
-spec entry_span(path_entry()) -> molt@types:span().
entry_span(Entry) ->
case Entry of
{explicit_table, Span} ->
Span;
{explicit_array_of_tables, _, Span@1} ->
Span@1;
{header_implicit, Span@2} ->
Span@2;
{dotted_implicit, Span@3} ->
Span@3;
{closed_implicit, Span@4} ->
Span@4;
{explicit_scalar, Span@5} ->
Span@5;
{explicit_inline_table, Span@6} ->
Span@6;
{explicit_inline_array, Span@7} ->
Span@7
end.
-file("src/molt/internal/validate.gleam", 674).
?DOC(false).
-spec value_kind_entry(value_kind(), pos()) -> path_entry().
value_kind_entry(Value_kind, Pos) ->
Span = pos_span(Pos),
case Value_kind of
scalar_value ->
{explicit_scalar, Span};
inline_table_value ->
{explicit_inline_table, Span};
inline_array_value ->
{explicit_inline_array, Span}
end.
-file("src/molt/internal/validate.gleam", 1230).
?DOC(false).
-spec last_or_empty(list(binary())) -> binary().
last_or_empty(L) ->
_pipe = gleam@list:last(L),
gleam@result:unwrap(_pipe, <<""/utf8>>).
-file("src/molt/internal/validate.gleam", 1222).
?DOC(false).
-spec list_init(list(binary())) -> list(binary()).
list_init(L) ->
case L of
[] ->
[];
[_] ->
[];
_ ->
gleam@list:take(L, erlang:length(L) - 1)
end.
-file("src/molt/internal/validate.gleam", 686).
?DOC(false).
-spec emit_descent_error(
state(IQJ),
list(binary()),
fun((binary()) -> molt@types:syntax_error_kind())
) -> state(IQJ).
emit_descent_error(State, Prefix, Kind_with_key) ->
Key = last_or_empty(Prefix),
Parent = list_init(Prefix),
emit(State, fun() -> make_error(State, Kind_with_key(Key), Parent) end).
-file("src/molt/internal/validate.gleam", 619).
?DOC(false).
-spec register_dotted_implicit_parents(state(IQD), list(list(binary()))) -> state(IQD).
register_dotted_implicit_parents(State, Parent_paths) ->
Span = pos_span(erlang:element(4, State)),
gleam@list:fold(
Parent_paths,
State,
fun(State@1, Prefix) ->
case gleam_stdlib:map_get(erlang:element(7, State@1), Prefix) of
{error, nil} ->
{state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(
erlang:element(7, State@1),
Prefix,
{dotted_implicit, Span}
),
erlang:element(8, State@1),
erlang:element(9, State@1)};
{ok, {dotted_implicit, _}} ->
State@1;
{ok, {explicit_scalar, Original}} ->
emit_descent_error(
State@1,
Prefix,
fun(Key) -> {key_is_scalar, Key, Original} end
);
{ok, {explicit_inline_table, Original@1}} ->
emit_descent_error(
State@1,
Prefix,
fun(Key@1) ->
{key_is_inline_table, Key@1, Original@1}
end
);
{ok, {explicit_inline_array, Original@2}} ->
emit_descent_error(
State@1,
Prefix,
fun(Key@2) -> {key_is_array, Key@2, Original@2} end
);
{ok, Entry} ->
Original@3 = entry_span(Entry),
emit(
State@1,
fun() ->
make_error(
State@1,
{duplicate_table, Original@3},
Prefix
)
end
)
end
end
).
-file("src/molt/internal/validate.gleam", 558).
?DOC(false).
-spec register_kv_path(state(IPU), list(binary()), list(binary()), value_kind()) -> state(IPU).
register_kv_path(State, Table_path, Segments, Value_kind) ->
Full_path = lists:append(Table_path, Segments),
Table_len = erlang:length(Table_path),
Dotted_prefixes = gleam@list:drop(
molt@internal@utils:all_prefixes(Full_path),
Table_len
),
State@1 = register_dotted_implicit_parents(State, Dotted_prefixes),
Key = last_or_empty(Segments),
Entry = value_kind_entry(Value_kind, erlang:element(4, State@1)),
case gleam_stdlib:map_get(erlang:element(7, State@1), Full_path) of
{error, nil} ->
{state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(erlang:element(7, State@1), Full_path, Entry),
erlang:element(8, State@1),
erlang:element(9, State@1)};
{ok, Existing} ->
Original = entry_span(Existing),
State@2 = {state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(erlang:element(7, State@1), Full_path, Entry),
erlang:element(8, State@1),
erlang:element(9, State@1)},
emit(
State@2,
fun() ->
make_error(
State@2,
{duplicate_key, Key, Original},
Table_path
)
end
)
end.
-file("src/molt/internal/validate.gleam", 128).
?DOC(false).
-spec enrich_collector() -> collector(list(molt@types:syntax_error())).
enrich_collector() ->
{collector, [], true, fun(Errors, Build) -> [Build() | Errors] end}.
-file("src/molt/internal/validate.gleam", 1212).
?DOC(false).
-spec skip_inline_value(list(greenwood:element(molt@types:toml_kind()))) -> list(greenwood:element(molt@types:toml_kind())).
skip_inline_value(Children) ->
case molt@internal@cst@elements:skip_all_trivia(Children) of
[] ->
[];
[{node_element, _} | Rest] ->
Rest;
[{token_element, _} | Rest@1] ->
Rest@1
end.
-file("src/molt/internal/validate.gleam", 1202).
?DOC(false).
-spec skip_to_equals_value(list(greenwood:element(molt@types:toml_kind()))) -> list(greenwood:element(molt@types:toml_kind())).
skip_to_equals_value(Children) ->
case Children of
[] ->
[];
[{token_element, {token, equals, _}} | Rest] ->
Rest;
[_ | Rest@1] ->
skip_to_equals_value(Rest@1)
end.
-file("src/molt/internal/validate.gleam", 1154).
?DOC(false).
-spec take_inline_key_segments(
list(greenwood:element(molt@types:toml_kind())),
list(binary())
) -> {list(binary()), list(greenwood:element(molt@types:toml_kind()))}.
take_inline_key_segments(Children, Acc) ->
case molt@internal@cst@elements:skip_all_trivia(Children) of
[] ->
{lists:reverse(Acc), []};
[{token_element, {token, equals, _}} | _] = Rest ->
{lists:reverse(Acc), Rest};
[{token_element, {token, bare_key, Text}} | Rest@1] ->
Segs = begin
_pipe = gleam@string:split(Text, <<"."/utf8>>),
gleam@list:filter(_pipe, fun(S) -> S /= <<""/utf8>> end)
end,
take_inline_key_segments(
Rest@1,
lists:append(lists:reverse(Segs), Acc)
);
[{token_element, {token, integer, Text@1}} | Rest@2] ->
take_inline_key_segments(Rest@2, [Text@1 | Acc]);
[{token_element, {token, basic_string, Text@2}} | Rest@3] ->
take_inline_key_segments(
Rest@3,
[molt@internal@utils:unescape_basic_string(Text@2) | Acc]
);
[{token_element, {token, literal_string, Text@3}} | Rest@4] ->
take_inline_key_segments(Rest@4, [Text@3 | Acc]);
[{token_element, {token, dot, _}} | Rest@5] ->
take_inline_key_segments(Rest@5, Acc);
[_ | Rest@6] ->
take_inline_key_segments(Rest@6, Acc)
end.
-file("src/molt/internal/validate.gleam", 1177).
?DOC(false).
-spec take_inline_key_segments_from_kv(
list(greenwood:element(molt@types:toml_kind())),
list(binary())
) -> list(binary()).
take_inline_key_segments_from_kv(Children, Acc) ->
case Children of
[] ->
lists:reverse(Acc);
[{token_element, {token, equals, _}} | _] ->
lists:reverse(Acc);
[{token_element, {token, whitespace, _}} | Rest] ->
take_inline_key_segments_from_kv(Rest, Acc);
[{token_element, {token, dot, _}} | Rest] ->
take_inline_key_segments_from_kv(Rest, Acc);
[{token_element, {token, bare_key, Text}} | Rest@1] ->
take_inline_key_segments_from_kv(Rest@1, [Text | Acc]);
[{token_element, {token, integer, Text@1}} | Rest@2] ->
take_inline_key_segments_from_kv(Rest@2, [Text@1 | Acc]);
[{token_element, {token, basic_string, Text@2}} | Rest@3] ->
take_inline_key_segments_from_kv(
Rest@3,
[molt@internal@utils:unescape_basic_string(Text@2) | Acc]
);
[{token_element, {token, literal_string, Text@3}} | Rest@4] ->
take_inline_key_segments_from_kv(Rest@4, [Text@3 | Acc]);
[_ | Rest@5] ->
take_inline_key_segments_from_kv(Rest@5, Acc)
end.
-file("src/molt/internal/validate.gleam", 1125).
?DOC(false).
-spec extract_inline_key_paths(
list(greenwood:element(molt@types:toml_kind())),
list(list(binary()))
) -> list(list(binary())).
extract_inline_key_paths(Children, Acc) ->
case molt@internal@cst@elements:skip_all_trivia(Children) of
[] ->
lists:reverse(Acc);
[{token_element, {token, left_brace, _}} | Rest] ->
extract_inline_key_paths(Rest, Acc);
[{token_element, {token, right_brace, _}} | _] ->
lists:reverse(Acc);
[{token_element, {token, comma, _}} | Rest@1] ->
extract_inline_key_paths(Rest@1, Acc);
[{node_element, N} | Rest@2] when erlang:element(2, N) =:= key_value ->
case take_inline_key_segments_from_kv(erlang:element(3, N), []) of
[] ->
extract_inline_key_paths(Rest@2, Acc);
Segments ->
extract_inline_key_paths(Rest@2, [Segments | Acc])
end;
Rest@3 ->
{Segments@1, After_key} = take_inline_key_segments(Rest@3, []),
After_eq = skip_to_equals_value(After_key),
After_value = skip_inline_value(After_eq),
case Segments@1 of
[] ->
extract_inline_key_paths(After_value, Acc);
_ ->
extract_inline_key_paths(After_value, [Segments@1 | Acc])
end
end.
-file("src/molt/internal/validate.gleam", 1088).
?DOC(false).
-spec inline_table_first_duplicate_key(
list(greenwood:element(molt@types:toml_kind()))
) -> gleam@option:option(binary()).
inline_table_first_duplicate_key(Children) ->
Key_paths = extract_inline_key_paths(Children, []),
State = {state,
enrich_collector(),
[],
{pos, 0, 0, 0},
[],
[],
maps:new(),
maps:new(),
0},
State@2 = gleam@list:fold(
Key_paths,
State,
fun(State@1, Segments) ->
register_kv_path(State@1, [], Segments, scalar_value)
end
),
_pipe = lists:reverse(erlang:element(3, State@2)),
_pipe@1 = gleam@list:find_map(
_pipe,
fun(Err) -> case erlang:element(2, Err) of
{duplicate_key, Key, _} ->
{ok, Key};
{key_is_scalar, Key, _} ->
{ok, Key};
{key_is_inline_table, Key, _} ->
{ok, Key};
{key_is_array, Key, _} ->
{ok, Key};
_ ->
{error, nil}
end end
),
gleam@option:from_result(_pipe@1).
-file("src/molt/internal/validate.gleam", 1026).
?DOC(false).
-spec inline_table_is_closed(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
inline_table_is_closed(Children) ->
gleam@list:any(Children, fun(El) -> case El of
{token_element, {token, right_brace, _}} ->
true;
_ ->
false
end end).
-file("src/molt/internal/validate.gleam", 770).
?DOC(false).
-spec check_inline_table_syntax(
state(IRG),
greenwood:node_(molt@types:toml_kind()),
list(binary())
) -> state(IRG).
check_inline_table_syntax(State, Node, Path) ->
State@1 = case inline_table_is_closed(erlang:element(3, Node)) of
true ->
State;
false ->
push_error(State, unterminated_inline_table, Path)
end,
State@2 = case inline_table_first_duplicate_key(erlang:element(3, Node)) of
none ->
State@1;
{some, Key} ->
push_error(State@1, {duplicate_key_in_inline_table, Key}, Path)
end,
State@3 = case inline_table_bare_values_ok(erlang:element(3, Node)) of
true ->
State@2;
false ->
push_error(State@2, invalid_bare_value_in_inline_table, Path)
end,
case inline_table_commas_ok(erlang:element(3, Node)) of
true ->
State@3;
false ->
push_error(State@3, misplaced_inline_table_separator, Path)
end.
-file("src/molt/internal/validate.gleam", 1011).
?DOC(false).
-spec do_element_value_count(
list(greenwood:element(molt@types:toml_kind())),
integer()
) -> boolean().
do_element_value_count(Children, Count) ->
case Children of
[] ->
Count =:= 1;
[{token_element, {token, whitespace, _}} | Rest] ->
do_element_value_count(Rest, Count);
[{token_element, {token, newline, _}} | Rest] ->
do_element_value_count(Rest, Count);
[{token_element, {token, comment, _}} | Rest] ->
do_element_value_count(Rest, Count);
[{token_element, {token, comma, _}} | Rest] ->
do_element_value_count(Rest, Count);
[_ | Rest@1] ->
do_element_value_count(Rest@1, Count + 1)
end.
-file("src/molt/internal/validate.gleam", 1007).
?DOC(false).
-spec element_has_single_value(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
element_has_single_value(Children) ->
do_element_value_count(Children, 0).
-file("src/molt/internal/validate.gleam", 990).
?DOC(false).
-spec do_array_seps_ok(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
do_array_seps_ok(Children) ->
case Children of
[] ->
true;
[{token_element, {token, right_bracket, _}} | _] ->
true;
[{token_element, {token, left_bracket, _}} | Rest] ->
do_array_seps_ok(Rest);
[{token_element, {token, whitespace, _}} | Rest@1] ->
do_array_seps_ok(Rest@1);
[{token_element, {token, newline, _}} | Rest@1] ->
do_array_seps_ok(Rest@1);
[{token_element, {token, comment, _}} | Rest@1] ->
do_array_seps_ok(Rest@1);
[{node_element, N} | Rest@2] when erlang:element(2, N) =:= array_element ->
gleam@bool:guard(
not element_has_single_value(erlang:element(3, N)),
false,
fun() -> do_array_seps_ok(Rest@2) end
);
[{token_element, {token, comma, _}} | _] ->
false;
[_ | _] ->
false
end.
-file("src/molt/internal/validate.gleam", 986).
?DOC(false).
-spec array_separators_ok(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
array_separators_ok(Children) ->
do_array_seps_ok(Children).
-file("src/molt/internal/validate.gleam", 977).
?DOC(false).
-spec array_is_closed(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
array_is_closed(Children) ->
gleam@list:any(Children, fun(El) -> case El of
{token_element, {token, right_bracket, _}} ->
true;
_ ->
false
end end).
-file("src/molt/internal/validate.gleam", 753).
?DOC(false).
-spec check_array_syntax(
state(IRB),
greenwood:node_(molt@types:toml_kind()),
list(binary())
) -> state(IRB).
check_array_syntax(State, Node, Path) ->
State@1 = case array_is_closed(erlang:element(3, Node)) of
true ->
State;
false ->
push_error(State, unterminated_array, Path)
end,
gleam@bool:guard(
array_separators_ok(erlang:element(3, Node)),
State@1,
fun() -> push_error(State@1, misplaced_array_separator, Path) end
).
-file("src/molt/internal/validate.gleam", 865).
?DOC(false).
-spec do_has_single_value(
list(greenwood:element(molt@types:toml_kind())),
boolean()
) -> boolean().
do_has_single_value(Children, Saw_value) ->
case Children of
[] ->
true;
[{token_element, {token, whitespace, _}} | Rest] ->
do_has_single_value(Rest, Saw_value);
[{token_element, {token, newline, _}} | Rest] ->
do_has_single_value(Rest, Saw_value);
[{token_element, {token, comment, _}} | Rest] ->
do_has_single_value(Rest, Saw_value);
[{token_element, {token, comma, _}} | Rest] ->
do_has_single_value(Rest, Saw_value);
[_ | Rest@1] ->
gleam@bool:guard(
Saw_value,
false,
fun() -> do_has_single_value(Rest@1, true) end
)
end.
-file("src/molt/internal/validate.gleam", 861).
?DOC(false).
-spec has_single_value(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
has_single_value(Value_tokens) ->
do_has_single_value(Value_tokens, false).
-file("src/molt/internal/validate.gleam", 852).
?DOC(false).
-spec has_extra_equals(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
has_extra_equals(Value_tokens) ->
gleam@list:any(Value_tokens, fun(El) -> case El of
{token_element, {token, equals, _}} ->
true;
_ ->
false
end end).
-file("src/molt/internal/validate.gleam", 840).
?DOC(false).
-spec has_value(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
has_value(Value_tokens) ->
gleam@list:any(Value_tokens, fun(El) -> case El of
{token_element, {token, whitespace, _}} ->
false;
{token_element, {token, newline, _}} ->
false;
{token_element, {token, comment, _}} ->
false;
{token_element, {token, equals, _}} ->
false;
_ ->
true
end end).
-file("src/molt/internal/validate.gleam", 800).
?DOC(false).
-spec do_check_key_tokens_ok(
list(greenwood:element(molt@types:toml_kind())),
boolean()
) -> boolean().
do_check_key_tokens_ok(Children, Seen_key) ->
case Children of
[] ->
Seen_key;
[{token_element, {token, equals, _}} | _] ->
Seen_key;
[{token_element, {token, whitespace, _}} | Rest] ->
do_check_key_tokens_ok(Rest, Seen_key);
[{token_element, {token, dot, _}} | Rest@1] ->
case Seen_key of
true ->
do_check_key_tokens_ok(Rest@1, false);
false ->
false
end;
[{token_element, {token, bare_key, Text}} | Rest@2] ->
case Seen_key of
true ->
false;
false ->
case molt@internal@utils:is_bare_key(Text) of
true ->
do_check_key_tokens_ok(Rest@2, true);
false ->
false
end
end;
[{token_element, {token, integer, _}} | Rest@3] ->
case Seen_key of
true ->
false;
false ->
do_check_key_tokens_ok(Rest@3, true)
end;
[{token_element, {token, basic_string, _}} | Rest@3] ->
case Seen_key of
true ->
false;
false ->
do_check_key_tokens_ok(Rest@3, true)
end;
[{token_element, {token, literal_string, _}} | Rest@3] ->
case Seen_key of
true ->
false;
false ->
do_check_key_tokens_ok(Rest@3, true)
end;
[{node_element, N} | Rest@4] when erlang:element(2, N) =:= key ->
case check_key_tokens_ok(N) of
true ->
do_check_key_tokens_ok(Rest@4, true);
false ->
false
end;
_ ->
false
end.
-file("src/molt/internal/validate.gleam", 796).
?DOC(false).
-spec check_key_tokens_ok(greenwood:node_(molt@types:toml_kind())) -> boolean().
check_key_tokens_ok(Kv) ->
do_check_key_tokens_ok(erlang:element(3, Kv), false).
-file("src/molt/internal/validate.gleam", 698).
?DOC(false).
-spec check_kv_syntax(
state(IQN),
greenwood:node_(molt@types:toml_kind()),
list(binary())
) -> state(IQN).
check_kv_syntax(State, Node, Path) ->
State@1 = case check_key_tokens_ok(Node) of
true ->
State;
false ->
push_error(State, invalid_key_syntax, Path)
end,
Value_tokens = molt@internal@cst@elements:value_tokens(
erlang:element(3, Node)
),
State@2 = case has_value(Value_tokens) of
true ->
State@1;
false ->
push_error(State@1, missing_value, Path)
end,
State@3 = case has_extra_equals(Value_tokens) of
false ->
State@2;
true ->
push_error(State@2, extra_equals, Path)
end,
case has_single_value(Value_tokens) of
true ->
State@3;
false ->
push_error(State@3, multiple_values, Path)
end.
-file("src/molt/internal/validate.gleam", 661).
?DOC(false).
-spec kv_value_kind(greenwood:node_(molt@types:toml_kind())) -> value_kind().
kv_value_kind(Kv) ->
Value_tokens = molt@internal@cst@elements:value_tokens(
erlang:element(3, Kv)
),
case molt@internal@cst@elements:find_first_value(Value_tokens) of
{some, {node_element, N}} ->
case erlang:element(2, N) of
inline_table ->
inline_table_value;
array ->
inline_array_value;
_ ->
scalar_value
end;
_ ->
scalar_value
end.
-file("src/molt/internal/validate.gleam", 538).
?DOC(false).
-spec register_kv(
state(IPP),
list(binary()),
greenwood:node_(molt@types:toml_kind())
) -> state(IPP).
register_kv(State, Table_path, Kv) ->
case molt@internal@cst@elements:key_path(erlang:element(3, Kv)) of
none ->
emit(
State,
fun() -> make_error(State, invalid_key_syntax, Table_path) end
);
{some, Segments} ->
register_kv_path(State, Table_path, Segments, kv_value_kind(Kv))
end.
-file("src/molt/internal/validate.gleam", 967).
?DOC(false).
-spec only_trailing_trivia(list(greenwood:element(molt@types:toml_kind()))) -> boolean().
only_trailing_trivia(Children) ->
case Children of
[] ->
true;
[{token_element, {token, newline, _}} | _] ->
true;
[{token_element, {token, whitespace, _}} | Rest] ->
only_trailing_trivia(Rest);
[{token_element, {token, comment, _}} | Rest] ->
only_trailing_trivia(Rest);
_ ->
false
end.
-file("src/molt/internal/validate.gleam", 908).
?DOC(false).
-spec consume_brackets_ok(
list(greenwood:element(molt@types:toml_kind())),
integer(),
molt@types:toml_kind()
) -> {ok, list(greenwood:element(molt@types:toml_kind()))} | {error, nil}.
consume_brackets_ok(Children, Count, Bracket) ->
gleam@bool:guard(Count =:= 0, {ok, Children}, fun() -> case Children of
[{token_element, {token, K, _}} | Children@1] when K =:= Bracket ->
consume_brackets_ok(Children@1, Count - 1, Bracket);
_ ->
{error, nil}
end end).
-file("src/molt/internal/validate.gleam", 940).
?DOC(false).
-spec do_check_header_keys_ok(
list(greenwood:element(molt@types:toml_kind())),
boolean()
) -> boolean().
do_check_header_keys_ok(Tokens, Seen_key) ->
case Tokens of
[] ->
Seen_key;
[{token_element, {token, whitespace, _}} | Rest] ->
do_check_header_keys_ok(Rest, Seen_key);
[{token_element, {token, dot, _}} | Rest@1] ->
gleam@bool:guard(
not Seen_key,
false,
fun() -> do_check_header_keys_ok(Rest@1, false) end
);
[{token_element, {token, bare_key, Text}} | Rest@2] ->
gleam@bool:guard(
Seen_key,
false,
fun() ->
gleam@bool:guard(
not molt@internal@utils:is_bare_key(Text),
false,
fun() -> do_check_header_keys_ok(Rest@2, true) end
)
end
);
[{token_element, {token, basic_string, _}} | Rest@3] ->
gleam@bool:guard(
Seen_key,
false,
fun() -> do_check_header_keys_ok(Rest@3, true) end
);
[{token_element, {token, literal_string, _}} | Rest@3] ->
gleam@bool:guard(
Seen_key,
false,
fun() -> do_check_header_keys_ok(Rest@3, true) end
);
[{token_element, {token, integer, _}} | Rest@3] ->
gleam@bool:guard(
Seen_key,
false,
fun() -> do_check_header_keys_ok(Rest@3, true) end
);
_ ->
false
end.
-file("src/molt/internal/validate.gleam", 936).
?DOC(false).
-spec check_header_key_tokens_ok(
list(greenwood:element(molt@types:toml_kind()))
) -> boolean().
check_header_key_tokens_ok(Tokens) ->
do_check_header_keys_ok(Tokens, false).
-file("src/molt/internal/validate.gleam", 922).
?DOC(false).
-spec take_until_right_bracket(
list(greenwood:element(molt@types:toml_kind())),
list(greenwood:element(molt@types:toml_kind()))
) -> {list(greenwood:element(molt@types:toml_kind())),
list(greenwood:element(molt@types:toml_kind()))}.
take_until_right_bracket(Children, Acc) ->
case Children of
[] ->
{lists:reverse(Acc), []};
[{token_element, {token, right_bracket, _}} | _] ->
{lists:reverse(Acc), Children};
[El | Rest] ->
take_until_right_bracket(Rest, [El | Acc])
end.
-file("src/molt/internal/validate.gleam", 883).
?DOC(false).
-spec check_table_bracket_shape_ok(
list(greenwood:element(molt@types:toml_kind())),
integer()
) -> boolean().
check_table_bracket_shape_ok(Children, Expected) ->
Children@1 = molt@internal@cst@elements:skip_trivia(Children),
case consume_brackets_ok(Children@1, Expected, left_bracket) of
{error, nil} ->
false;
{ok, Rest} ->
{Key_tokens, Children@2} = take_until_right_bracket(Rest, []),
gleam@bool:guard(
not check_header_key_tokens_ok(Key_tokens),
false,
fun() ->
_pipe = consume_brackets_ok(
Children@2,
Expected,
right_bracket
),
_pipe@1 = gleam@result:map(
_pipe,
fun only_trailing_trivia/1
),
gleam@result:unwrap(_pipe@1, false)
end
)
end.
-file("src/molt/internal/validate.gleam", 732).
?DOC(false).
-spec check_table_header_syntax(
state(IQW),
greenwood:node_(molt@types:toml_kind()),
list(binary())
) -> state(IQW).
check_table_header_syntax(State, Node, Path) ->
gleam@bool:lazy_guard(
Path =:= [],
fun() -> push_error(State, empty_table_header, Path) end,
fun() ->
Expected = case erlang:element(2, Node) of
array_of_tables ->
2;
_ ->
1
end,
gleam@bool:guard(
check_table_bracket_shape_ok(erlang:element(3, Node), Expected),
State,
fun() -> push_error(State, malformed_table_header, Path) end
)
end
).
-file("src/molt/internal/validate.gleam", 437).
?DOC(false).
-spec do_scope_path(
state(any()),
list(binary()),
list(binary()),
list(binary()),
boolean()
) -> list(binary()).
do_scope_path(State, Remaining, Raw_current, Scoped_current, Scope_terminal) ->
case Remaining of
[] ->
Scoped_current;
[Segment | Rest] ->
Raw_prefix = lists:append(Raw_current, [Segment]),
Scoped_prefix = lists:append(Scoped_current, [Segment]),
Scope_here = Scope_terminal orelse (Rest /= []),
case {Scope_here,
gleam_stdlib:map_get(erlang:element(8, State), Raw_prefix)} of
{true, {ok, Instance}} ->
do_scope_path(
State,
Rest,
Raw_prefix,
lists:append(
Scoped_prefix,
[erlang:integer_to_binary(Instance)]
),
Scope_terminal
);
{_, _} ->
do_scope_path(
State,
Rest,
Raw_prefix,
Scoped_prefix,
Scope_terminal
)
end
end.
-file("src/molt/internal/validate.gleam", 417).
?DOC(false).
-spec scope_path(state(any()), list(binary())) -> list(binary()).
scope_path(State, Path) ->
do_scope_path(State, Path, [], [], true).
-file("src/molt/internal/validate.gleam", 589).
?DOC(false).
-spec register_header_implicit_parents(state(IPZ), list(binary())) -> state(IPZ).
register_header_implicit_parents(State, Path) ->
Parent_paths = molt@internal@utils:all_prefixes(Path),
Span = pos_span(erlang:element(4, State)),
gleam@list:fold(
Parent_paths,
State,
fun(State@1, Prefix) ->
case gleam_stdlib:map_get(erlang:element(7, State@1), Prefix) of
{error, nil} ->
{state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(
erlang:element(7, State@1),
Prefix,
{header_implicit, Span}
),
erlang:element(8, State@1),
erlang:element(9, State@1)};
{ok, {explicit_scalar, Original}} ->
emit_descent_error(
State@1,
Prefix,
fun(Key) -> {key_is_scalar, Key, Original} end
);
{ok, {explicit_inline_table, Original@1}} ->
emit_descent_error(
State@1,
Prefix,
fun(Key@1) ->
{key_is_inline_table, Key@1, Original@1}
end
);
{ok, {explicit_inline_array, Original@2}} ->
emit_descent_error(
State@1,
Prefix,
fun(Key@2) -> {key_is_array, Key@2, Original@2} end
);
{ok, _} ->
State@1
end
end
).
-file("src/molt/internal/validate.gleam", 427).
?DOC(false).
-spec scope_header_path(state(any()), list(binary())) -> list(binary()).
scope_header_path(State, Path) ->
do_scope_path(State, Path, [], [], false).
-file("src/molt/internal/validate.gleam", 496).
?DOC(false).
-spec register_array_of_tables(state(IPL), list(binary())) -> state(IPL).
register_array_of_tables(State, Raw_path) ->
Span = pos_span(erlang:element(4, State)),
Scoped = scope_header_path(State, Raw_path),
State@1 = register_header_implicit_parents(State, Scoped),
Count = begin
_pipe = gleam_stdlib:map_get(erlang:element(8, State@1), Raw_path),
gleam@result:unwrap(_pipe, -1)
end
+ 1,
State@2 = {state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
erlang:element(7, State@1),
gleam@dict:insert(erlang:element(8, State@1), Raw_path, Count),
erlang:element(9, State@1)},
case gleam_stdlib:map_get(erlang:element(7, State@2), Scoped) of
{error, nil} ->
{state,
erlang:element(2, State@2),
erlang:element(3, State@2),
erlang:element(4, State@2),
erlang:element(5, State@2),
erlang:element(6, State@2),
gleam@dict:insert(
erlang:element(7, State@2),
Scoped,
{explicit_array_of_tables, Count, Span}
),
erlang:element(8, State@2),
erlang:element(9, State@2)};
{ok, {explicit_array_of_tables, _, _}} ->
{state,
erlang:element(2, State@2),
erlang:element(3, State@2),
erlang:element(4, State@2),
erlang:element(5, State@2),
erlang:element(6, State@2),
gleam@dict:insert(
erlang:element(7, State@2),
Scoped,
{explicit_array_of_tables, Count, Span}
),
erlang:element(8, State@2),
erlang:element(9, State@2)};
{ok, Entry} ->
Original = entry_span(Entry),
State@3 = {state,
erlang:element(2, State@2),
erlang:element(3, State@2),
erlang:element(4, State@2),
erlang:element(5, State@2),
erlang:element(6, State@2),
gleam@dict:insert(
erlang:element(7, State@2),
Scoped,
{explicit_array_of_tables, Count, Span}
),
erlang:element(8, State@2),
erlang:element(9, State@2)},
emit(
State@3,
fun() ->
make_error(State@3, {duplicate_table, Original}, Scoped)
end
)
end.
-file("src/molt/internal/validate.gleam", 405).
?DOC(false).
-spec freeze_dotted(state(IOQ)) -> state(IOQ).
freeze_dotted(State) ->
{state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
gleam@dict:map_values(erlang:element(7, State), fun(_, V) -> case V of
{dotted_implicit, Span} ->
{closed_implicit, Span};
_ ->
V
end end),
erlang:element(8, State),
erlang:element(9, State)}.
-file("src/molt/internal/validate.gleam", 473).
?DOC(false).
-spec register_table(state(IPH), list(binary())) -> state(IPH).
register_table(State, Path) ->
Span = pos_span(erlang:element(4, State)),
State@1 = register_header_implicit_parents(State, Path),
case gleam_stdlib:map_get(erlang:element(7, State@1), Path) of
{error, nil} ->
{state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(
erlang:element(7, State@1),
Path,
{explicit_table, Span}
),
erlang:element(8, State@1),
erlang:element(9, State@1)};
{ok, {header_implicit, _}} ->
{state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(
erlang:element(7, State@1),
Path,
{explicit_table, Span}
),
erlang:element(8, State@1),
erlang:element(9, State@1)};
{ok, Entry} ->
Original = entry_span(Entry),
State@2 = {state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
gleam@dict:insert(
erlang:element(7, State@1),
Path,
{explicit_table, Span}
),
erlang:element(8, State@1),
erlang:element(9, State@1)},
emit(
State@2,
fun() ->
make_error(State@2, {duplicate_table, Original}, Path)
end
)
end.
-file("src/molt/internal/validate.gleam", 194).
?DOC(false).
-spec enter_node(state(INR), greenwood:node_(molt@types:toml_kind())) -> state(INR).
enter_node(State, Node) ->
case erlang:element(2, Node) of
root ->
State;
error ->
State@1 = emit(
State,
fun() ->
make_error(
State,
unparsable_content,
erlang:element(5, State)
)
end
),
{state,
erlang:element(2, State@1),
erlang:element(3, State@1),
erlang:element(4, State@1),
erlang:element(5, State@1),
erlang:element(6, State@1),
erlang:element(7, State@1),
erlang:element(8, State@1),
erlang:element(9, State@1) + 1};
table ->
Table_path = molt@internal@cst@elements:extract_key_segments(
erlang:element(3, Node)
),
State@2 = freeze_dotted(State),
Scoped = scope_header_path(State@2, Table_path),
State@3 = push_path(State@2, Scoped),
_pipe = register_table(State@3, Scoped),
check_table_header_syntax(_pipe, Node, Table_path);
array_of_tables ->
Table_path@1 = molt@internal@cst@elements:extract_key_segments(
erlang:element(3, Node)
),
State@4 = begin
_pipe@1 = freeze_dotted(State),
register_array_of_tables(_pipe@1, Table_path@1)
end,
Instance = begin
_pipe@2 = gleam_stdlib:map_get(
erlang:element(8, State@4),
Table_path@1
),
gleam@result:unwrap(_pipe@2, 1)
end
- 1,
Last = last_or_empty(Table_path@1),
Scoped_parent = scope_path(State@4, list_init(Table_path@1)),
Scoped_path = lists:append(
Scoped_parent,
[Last, erlang:integer_to_binary(Instance)]
),
_pipe@3 = push_path(State@4, Scoped_path),
check_table_header_syntax(_pipe@3, Node, Table_path@1);
key_value ->
State@5 = case erlang:element(9, State) of
0 ->
register_kv(State, erlang:element(5, State), Node);
_ ->
State
end,
Kv_path = lists:append(
erlang:element(5, State@5),
begin
_pipe@4 = molt@internal@cst@elements:key_path(
erlang:element(3, Node)
),
gleam@option:unwrap(_pipe@4, [])
end
),
_pipe@5 = push_path(State@5, Kv_path),
check_kv_syntax(_pipe@5, Node, Kv_path);
array ->
State@6 = {state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State) + 1},
State@7 = push_path(State@6, erlang:element(5, State@6)),
check_array_syntax(State@7, Node, erlang:element(5, State@7));
inline_table ->
State@8 = {state,
erlang:element(2, State),
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State) + 1},
State@9 = push_path(State@8, erlang:element(5, State@8)),
check_inline_table_syntax(State@9, Node, erlang:element(5, State@9));
_ ->
push_path(State, erlang:element(5, State))
end.
-file("src/molt/internal/validate.gleam", 361).
?DOC(false).
-spec count_newlines(binary(), integer(), integer()) -> {integer(), integer()}.
count_newlines(Text, Line, Col) ->
case Text of
<<""/utf8>> ->
{Line, Col};
<<"\r\n"/utf8, Rest/binary>> ->
count_newlines(Rest, Line + 1, 1);
<<"\n"/utf8, Rest/binary>> ->
count_newlines(Rest, Line + 1, 1);
_ ->
case gleam_stdlib:string_pop_grapheme(Text) of
{ok, {_, Rest@1}} ->
count_newlines(Rest@1, Line, Col + 1);
{error, nil} ->
{Line, Col}
end
end.
-file("src/molt/internal/validate.gleam", 324).
?DOC(false).
-spec advance_text(state(IOK), binary(), molt@types:toml_kind()) -> state(IOK).
advance_text(State, Text, Kind) ->
{pos, Line, Col, Offset} = erlang:element(4, State),
Text@1 = case Kind of
equals ->
<<"="/utf8>>;
dot ->
<<"."/utf8>>;
comma ->
<<","/utf8>>;
left_bracket ->
<<"["/utf8>>;
right_bracket ->
<<"]"/utf8>>;
left_brace ->
<<"{"/utf8>>;
right_brace ->
<<"}"/utf8>>;
basic_string ->
<<<<"\""/utf8, Text/binary>>/binary, "\""/utf8>>;
literal_string ->
<<<<"'"/utf8, Text/binary>>/binary, "'"/utf8>>;
multiline_basic_string ->
<<<<"\"\"\""/utf8, Text/binary>>/binary, "\"\"\""/utf8>>;
multiline_basic_string_nl ->
<<<<"\"\"\"\n"/utf8, Text/binary>>/binary, "\"\"\""/utf8>>;
multiline_literal_string ->
<<<<"'''"/utf8, Text/binary>>/binary, "'''"/utf8>>;
multiline_literal_string_nl ->
<<<<"'''\n"/utf8, Text/binary>>/binary, "'''"/utf8>>;
_ ->
Text
end,
Len = erlang:byte_size(Text@1),
{New_line, New_col} = count_newlines(Text@1, Line, Col),
{state,
erlang:element(2, State),
erlang:element(3, State),
{pos, New_line, New_col, Offset + Len},
erlang:element(5, State),
erlang:element(6, State),
erlang:element(7, State),
erlang:element(8, State),
erlang:element(9, State)}.
-file("src/molt/internal/validate.gleam", 299).
?DOC(false).
-spec advance_token(state(IOG), greenwood:token(molt@types:toml_kind())) -> state(IOG).
advance_token(State, Token) ->
State@1 = case erlang:element(2, Token) of
invalid_value ->
emit(
State,
fun() ->
make_error(State, {bad_value, erlang:element(3, Token)}, [])
end
);
invalid_basic_string ->
emit(State, fun() -> make_error(State, unterminated_string, []) end);
invalid_literal_string ->
emit(State, fun() -> make_error(State, unterminated_string, []) end);
invalid_multiline_basic_string ->
emit(
State,
fun() ->
make_error(State, unterminated_multiline_string, [])
end
);
invalid_multiline_literal_string ->
emit(
State,
fun() ->
make_error(State, unterminated_multiline_string, [])
end
);
_ ->
State
end,
case erlang:element(3, erlang:element(2, State@1)) of
true ->
advance_text(
State@1,
erlang:element(3, Token),
erlang:element(2, Token)
);
false ->
State@1
end.
-file("src/molt/internal/validate.gleam", 137).
?DOC(false).
-spec walk(greenwood:node_(molt@types:toml_kind()), collector(INM)) -> INM.
walk(Tree, Collector) ->
case molt@internal@cst@elements:is_toml(erlang:element(3, Tree)) of
false ->
(erlang:element(4, Collector))(
erlang:element(2, Collector),
fun() ->
{syntax_error, no_valid_toml_structure, [], {span, 1, 1, 0}}
end
);
true ->
State = {state,
Collector,
erlang:element(2, Collector),
{pos, 1, 1, 0},
[],
[],
maps:new(),
maps:new(),
0},
Tree@1 = molt@internal@cst@elements:inline_trailing_trivia(Tree),
State@5 = begin
_pipe = greenwood:visitor(),
_pipe@1 = greenwood:on_trivia(
_pipe,
fun(State@1, Tok) ->
{continue, advance_token(State@1, Tok)}
end
),
_pipe@2 = greenwood:on_token(
_pipe@1,
fun(State@2, Tok@1) ->
{continue, advance_token(State@2, Tok@1)}
end
),
_pipe@3 = greenwood:on_enter_node(
_pipe@2,
fun(State@3, Node) ->
{continue, enter_node(State@3, Node)}
end
),
_pipe@4 = greenwood:on_exit_node(
_pipe@3,
fun(State@4, Node@1) ->
{continue, exit_node(State@4, Node@1)}
end
),
greenwood:traverse(Tree@1, State, _pipe@4)
end,
erlang:element(3, State@5)
end.
-file("src/molt/internal/validate.gleam", 107).
?DOC(false).
-spec count(greenwood:node_(molt@types:toml_kind())) -> integer().
count(Tree) ->
walk(Tree, {collector, 0, false, fun(N, _) -> N + 1 end}).
-file("src/molt/internal/validate.gleam", 120).
?DOC(false).
-spec enrich(greenwood:node_(molt@types:toml_kind())) -> list(molt@types:syntax_error()).
enrich(Tree) ->
_pipe = walk(Tree, enrich_collector()),
lists:reverse(_pipe).