aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/packages/tom/src
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/packages/tom/src')
-rw-r--r--aoc2023/build/packages/tom/src/tom.app.src8
-rw-r--r--aoc2023/build/packages/tom/src/tom.erl2140
-rw-r--r--aoc2023/build/packages/tom/src/tom.gleam1317
3 files changed, 0 insertions, 3465 deletions
diff --git a/aoc2023/build/packages/tom/src/tom.app.src b/aoc2023/build/packages/tom/src/tom.app.src
deleted file mode 100644
index 051649c..0000000
--- a/aoc2023/build/packages/tom/src/tom.app.src
+++ /dev/null
@@ -1,8 +0,0 @@
-{application, tom, [
- {vsn, "0.2.1"},
- {applications, [gleam_stdlib,
- gleeunit]},
- {description, "A pure Gleam TOML parser!"},
- {modules, [tom]},
- {registered, []}
-]}.
diff --git a/aoc2023/build/packages/tom/src/tom.erl b/aoc2023/build/packages/tom/src/tom.erl
deleted file mode 100644
index 4f5c071..0000000
--- a/aoc2023/build/packages/tom/src/tom.erl
+++ /dev/null
@@ -1,2140 +0,0 @@
--module(tom).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([get/2, get_int/2, get_float/2, get_bool/2, get_string/2, get_date/2, get_time/2, get_date_time/2, get_array/2, get_table/2, get_number/2, parse/1]).
--export_type([toml/0, date_time/0, date/0, time/0, offset/0, sign/0, parse_error/0, number_/0, get_error/0]).
-
--type toml() :: {int, integer()} |
- {float, float()} |
- {infinity, sign()} |
- {nan, sign()} |
- {bool, boolean()} |
- {string, binary()} |
- {date, date()} |
- {time, time()} |
- {date_time, date_time()} |
- {array, list(toml())} |
- {array_of_tables, list(gleam@map:map_(binary(), toml()))} |
- {table, gleam@map:map_(binary(), toml())} |
- {inline_table, gleam@map:map_(binary(), toml())}.
-
--type date_time() :: {date_time_value, date(), time(), offset()}.
-
--type date() :: {date_value, integer(), integer(), integer()}.
-
--type time() :: {time_value, integer(), integer(), integer(), integer()}.
-
--type offset() :: local | {offset, sign(), integer(), integer()}.
-
--type sign() :: positive | negative.
-
--type parse_error() :: {unexpected, binary(), binary()} |
- {key_already_in_use, list(binary())}.
-
--type number_() :: {number_int, integer()} |
- {number_float, float()} |
- {number_infinity, sign()} |
- {number_nan, sign()}.
-
--type get_error() :: {not_found, list(binary())} |
- {wrong_type, list(binary()), binary(), binary()}.
-
--spec classify(toml()) -> binary().
-classify(Toml) ->
- case Toml of
- {int, _} ->
- <<"Int"/utf8>>;
-
- {float, _} ->
- <<"Float"/utf8>>;
-
- {nan, positive} ->
- <<"NaN"/utf8>>;
-
- {nan, negative} ->
- <<"Negative NaN"/utf8>>;
-
- {infinity, positive} ->
- <<"Infinity"/utf8>>;
-
- {infinity, negative} ->
- <<"Negative Infinity"/utf8>>;
-
- {bool, _} ->
- <<"Bool"/utf8>>;
-
- {string, _} ->
- <<"String"/utf8>>;
-
- {date, _} ->
- <<"Date"/utf8>>;
-
- {time, _} ->
- <<"Time"/utf8>>;
-
- {date_time, _} ->
- <<"DateTime"/utf8>>;
-
- {array, _} ->
- <<"Array"/utf8>>;
-
- {array_of_tables, _} ->
- <<"Array"/utf8>>;
-
- {table, _} ->
- <<"Table"/utf8>>;
-
- {inline_table, _} ->
- <<"Table"/utf8>>
- end.
-
--spec push_key({ok, FIU} | {error, get_error()}, binary()) -> {ok, FIU} |
- {error, get_error()}.
-push_key(Result, Key) ->
- case Result of
- {ok, T} ->
- {ok, T};
-
- {error, {not_found, Path}} ->
- {error, {not_found, [Key | Path]}};
-
- {error, {wrong_type, Path@1, Expected, Got}} ->
- {error, {wrong_type, [Key | Path@1], Expected, Got}}
- end.
-
--spec get(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, toml()} |
- {error, get_error()}.
-get(Toml, Key) ->
- case Key of
- [] ->
- {error, {not_found, []}};
-
- [K] ->
- gleam@result:replace_error(gleam@map:get(Toml, K), {not_found, [K]});
-
- [K@1 | Key@1] ->
- case gleam@map:get(Toml, K@1) of
- {ok, {table, T}} ->
- push_key(get(T, Key@1), K@1);
-
- {ok, Other} ->
- {error,
- {wrong_type, [K@1], <<"Table"/utf8>>, classify(Other)}};
-
- {error, _} ->
- {error, {not_found, [K@1]}}
- end
- end.
-
--spec get_int(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- integer()} |
- {error, get_error()}.
-get_int(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {int, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Int"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_float(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- float()} |
- {error, get_error()}.
-get_float(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {float, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Float"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_bool(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- boolean()} |
- {error, get_error()}.
-get_bool(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {bool, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Bool"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_string(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- binary()} |
- {error, get_error()}.
-get_string(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {string, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"String"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_date(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, date()} |
- {error, get_error()}.
-get_date(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {date, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Date"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_time(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, time()} |
- {error, get_error()}.
-get_time(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {time, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Time"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_date_time(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- date_time()} |
- {error, get_error()}.
-get_date_time(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {date_time, I}} ->
- {ok, I};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"DateTime"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_array(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- list(toml())} |
- {error, get_error()}.
-get_array(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {array, I}} ->
- {ok, I};
-
- {ok, {array_of_tables, I@1}} ->
- {ok, gleam@list:map(I@1, fun(Field@0) -> {table, Field@0} end)};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Array"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_table(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- gleam@map:map_(binary(), toml())} |
- {error, get_error()}.
-get_table(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {table, I}} ->
- {ok, I};
-
- {ok, {inline_table, I@1}} ->
- {ok, I@1};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Table"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec get_number(gleam@map:map_(binary(), toml()), list(binary())) -> {ok,
- number_()} |
- {error, get_error()}.
-get_number(Toml, Key) ->
- case get(Toml, Key) of
- {ok, {int, X}} ->
- {ok, {number_int, X}};
-
- {ok, {float, X@1}} ->
- {ok, {number_float, X@1}};
-
- {ok, {nan, X@2}} ->
- {ok, {number_nan, X@2}};
-
- {ok, {infinity, X@3}} ->
- {ok, {number_infinity, X@3}};
-
- {ok, Other} ->
- {error, {wrong_type, Key, <<"Number"/utf8>>, classify(Other)}};
-
- {error, E} ->
- {error, E}
- end.
-
--spec merge(gleam@map:map_(binary(), toml()), binary(), toml(), toml()) -> {ok,
- gleam@map:map_(binary(), toml())} |
- {error, list(binary())}.
-merge(Table, Key, Old, New) ->
- case {Old, New} of
- {{array_of_tables, Tables}, {array_of_tables, New@1}} ->
- {ok,
- gleam@map:insert(
- Table,
- Key,
- {array_of_tables, gleam@list:append(New@1, Tables)}
- )};
-
- {_, _} ->
- {error, [Key]}
- end.
-
--spec insert_loop(gleam@map:map_(binary(), toml()), list(binary()), toml()) -> {ok,
- gleam@map:map_(binary(), toml())} |
- {error, list(binary())}.
-insert_loop(Table, Key, Value) ->
- case Key of
- [] ->
- erlang:error(#{gleam_error => panic,
- message => <<"unreachable"/utf8>>,
- module => <<"tom"/utf8>>,
- function => <<"insert_loop"/utf8>>,
- line => 511});
-
- [K] ->
- case gleam@map:get(Table, K) of
- {error, nil} ->
- {ok, gleam@map:insert(Table, K, Value)};
-
- {ok, Old} ->
- merge(Table, K, Old, Value)
- end;
-
- [K@1 | Key@1] ->
- case gleam@map:get(Table, K@1) of
- {error, nil} ->
- case insert_loop(gleam@map:new(), Key@1, Value) of
- {ok, Inner} ->
- {ok, gleam@map:insert(Table, K@1, {table, Inner})};
-
- {error, Path} ->
- {error, [K@1 | Path]}
- end;
-
- {ok, {array_of_tables, [Inner@1 | Rest]}} ->
- case insert_loop(Inner@1, Key@1, Value) of
- {ok, Inner@2} ->
- {ok,
- gleam@map:insert(
- Table,
- K@1,
- {array_of_tables, [Inner@2 | Rest]}
- )};
-
- {error, Path@1} ->
- {error, [K@1 | Path@1]}
- end;
-
- {ok, {table, Inner@3}} ->
- case insert_loop(Inner@3, Key@1, Value) of
- {ok, Inner@4} ->
- {ok, gleam@map:insert(Table, K@1, {table, Inner@4})};
-
- {error, Path@2} ->
- {error, [K@1 | Path@2]}
- end;
-
- {ok, _} ->
- {error, [K@1]}
- end
- end.
-
--spec insert(gleam@map:map_(binary(), toml()), list(binary()), toml()) -> {ok,
- gleam@map:map_(binary(), toml())} |
- {error, parse_error()}.
-insert(Table, Key, Value) ->
- case insert_loop(Table, Key, Value) of
- {ok, Table@1} ->
- {ok, Table@1};
-
- {error, Path} ->
- {error, {key_already_in_use, Path}}
- end.
-
--spec expect_end_of_line(
- list(binary()),
- fun((list(binary())) -> {ok, {FKZ, list(binary())}} | {error, parse_error()})
-) -> {ok, {FKZ, list(binary())}} | {error, parse_error()}.
-expect_end_of_line(Input, Next) ->
- case Input of
- [<<"\n"/utf8>> | Input@1] ->
- Next(Input@1);
-
- [<<"\r\n"/utf8>> | Input@2] ->
- Next(Input@2);
-
- [G | _] ->
- {error, {unexpected, G, <<"\n"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"\n"/utf8>>}}
- end.
-
--spec parse_key_quoted(list(binary()), binary(), binary()) -> {ok,
- {binary(), list(binary())}} |
- {error, parse_error()}.
-parse_key_quoted(Input, Close, Name) ->
- case Input of
- [G | Input@1] when G =:= Close ->
- {ok, {Name, Input@1}};
-
- [G@1 | Input@2] ->
- parse_key_quoted(Input@2, Close, <<Name/binary, G@1/binary>>);
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, Close}}
- end.
-
--spec parse_key_bare(list(binary()), binary()) -> {ok,
- {binary(), list(binary())}} |
- {error, parse_error()}.
-parse_key_bare(Input, Name) ->
- case Input of
- [<<" "/utf8>> | Input@1] when Name =/= <<""/utf8>> ->
- {ok, {Name, Input@1}};
-
- [<<"="/utf8>> | _] when Name =/= <<""/utf8>> ->
- {ok, {Name, Input}};
-
- [<<"."/utf8>> | _] when Name =/= <<""/utf8>> ->
- {ok, {Name, Input}};
-
- [<<"]"/utf8>> | _] when Name =/= <<""/utf8>> ->
- {ok, {Name, Input}};
-
- [<<","/utf8>> | _] when Name =/= <<""/utf8>> ->
- {error, {unexpected, <<","/utf8>>, <<"="/utf8>>}};
-
- [<<"\n"/utf8>> | _] when Name =/= <<""/utf8>> ->
- {error, {unexpected, <<"\n"/utf8>>, <<"="/utf8>>}};
-
- [<<"\r\n"/utf8>> | _] when Name =/= <<""/utf8>> ->
- {error, {unexpected, <<"\r\n"/utf8>>, <<"="/utf8>>}};
-
- [<<"\n"/utf8>> | _] ->
- {error, {unexpected, <<"\n"/utf8>>, <<"key"/utf8>>}};
-
- [<<"\r\n"/utf8>> | _] ->
- {error, {unexpected, <<"\r\n"/utf8>>, <<"key"/utf8>>}};
-
- [<<"]"/utf8>> | _] ->
- {error, {unexpected, <<"]"/utf8>>, <<"key"/utf8>>}};
-
- [<<","/utf8>> | _] ->
- {error, {unexpected, <<","/utf8>>, <<"key"/utf8>>}};
-
- [G | Input@2] ->
- parse_key_bare(Input@2, <<Name/binary, G/binary>>);
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"key"/utf8>>}}
- end.
-
--spec skip_line_whitespace(list(binary())) -> list(binary()).
-skip_line_whitespace(Input) ->
- gleam@list:drop_while(
- Input,
- fun(G) -> (G =:= <<" "/utf8>>) orelse (G =:= <<"\t"/utf8>>) end
- ).
-
--spec parse_key_segment(list(binary())) -> {ok, {binary(), list(binary())}} |
- {error, parse_error()}.
-parse_key_segment(Input) ->
- Input@1 = skip_line_whitespace(Input),
- case Input@1 of
- [<<"="/utf8>> | _] ->
- {error, {unexpected, <<"="/utf8>>, <<"Key"/utf8>>}};
-
- [<<"\n"/utf8>> | _] ->
- {error, {unexpected, <<"\n"/utf8>>, <<"Key"/utf8>>}};
-
- [<<"\r\n"/utf8>> | _] ->
- {error, {unexpected, <<"\r\n"/utf8>>, <<"Key"/utf8>>}};
-
- [<<"["/utf8>> | _] ->
- {error, {unexpected, <<"["/utf8>>, <<"Key"/utf8>>}};
-
- [<<"\""/utf8>> | Input@2] ->
- parse_key_quoted(Input@2, <<"\""/utf8>>, <<""/utf8>>);
-
- [<<"'"/utf8>> | Input@3] ->
- parse_key_quoted(Input@3, <<"'"/utf8>>, <<""/utf8>>);
-
- _ ->
- parse_key_bare(Input@1, <<""/utf8>>)
- end.
-
--spec skip_whitespace(list(binary())) -> list(binary()).
-skip_whitespace(Input) ->
- case Input of
- [<<" "/utf8>> | Input@1] ->
- skip_whitespace(Input@1);
-
- [<<"\t"/utf8>> | Input@2] ->
- skip_whitespace(Input@2);
-
- [<<"\n"/utf8>> | Input@3] ->
- skip_whitespace(Input@3);
-
- [<<"\r\n"/utf8>> | Input@4] ->
- skip_whitespace(Input@4);
-
- Input@5 ->
- Input@5
- end.
-
--spec drop_comments(list(binary()), list(binary())) -> list(binary()).
-drop_comments(Input, Acc) ->
- case Input of
- [<<"#"/utf8>> | Input@1] ->
- _pipe = Input@1,
- _pipe@1 = gleam@list:drop_while(
- _pipe,
- fun(G) -> G /= <<"\n"/utf8>> end
- ),
- drop_comments(_pipe@1, Acc);
-
- [G@1 | Input@2] ->
- drop_comments(Input@2, [G@1 | Acc]);
-
- [] ->
- gleam@list:reverse(Acc)
- end.
-
--spec do(
- {ok, {FLK, list(binary())}} | {error, parse_error()},
- fun((FLK, list(binary())) -> {ok, FLN} | {error, parse_error()})
-) -> {ok, FLN} | {error, parse_error()}.
-do(Result, Next) ->
- case Result of
- {ok, {A, Input}} ->
- Next(A, Input);
-
- {error, E} ->
- {error, E}
- end.
-
--spec parse_key(list(binary()), list(binary())) -> {ok,
- {list(binary()), list(binary())}} |
- {error, parse_error()}.
-parse_key(Input, Segments) ->
- do(
- parse_key_segment(Input),
- fun(Segment, Input@1) ->
- Segments@1 = [Segment | Segments],
- Input@2 = skip_line_whitespace(Input@1),
- case Input@2 of
- [<<"."/utf8>> | Input@3] ->
- parse_key(Input@3, Segments@1);
-
- _ ->
- {ok, {gleam@list:reverse(Segments@1), Input@2}}
- end
- end
- ).
-
--spec expect(
- list(binary()),
- binary(),
- fun((list(binary())) -> {ok, {FLS, list(binary())}} | {error, parse_error()})
-) -> {ok, {FLS, list(binary())}} | {error, parse_error()}.
-expect(Input, Expected, Next) ->
- case Input of
- [G | Input@1] when G =:= Expected ->
- Next(Input@1);
-
- [G@1 | _] ->
- {error, {unexpected, G@1, Expected}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, Expected}}
- end.
-
--spec parse_table_header(list(binary())) -> {ok,
- {list(binary()), list(binary())}} |
- {error, parse_error()}.
-parse_table_header(Input) ->
- Input@1 = skip_line_whitespace(Input),
- do(
- parse_key(Input@1, []),
- fun(Key, Input@2) ->
- expect(
- Input@2,
- <<"]"/utf8>>,
- fun(Input@3) ->
- Input@4 = skip_line_whitespace(Input@3),
- expect_end_of_line(
- Input@4,
- fun(Input@5) -> {ok, {Key, Input@5}} end
- )
- end
- )
- end
- ).
-
--spec parse_hex(list(binary()), integer(), sign()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_hex(Input, Number, Sign) ->
- case Input of
- [<<"_"/utf8>> | Input@1] ->
- parse_hex(Input@1, Number, Sign);
-
- [<<"0"/utf8>> | Input@2] ->
- parse_hex(Input@2, (Number * 16) + 0, Sign);
-
- [<<"1"/utf8>> | Input@3] ->
- parse_hex(Input@3, (Number * 16) + 1, Sign);
-
- [<<"2"/utf8>> | Input@4] ->
- parse_hex(Input@4, (Number * 16) + 2, Sign);
-
- [<<"3"/utf8>> | Input@5] ->
- parse_hex(Input@5, (Number * 16) + 3, Sign);
-
- [<<"4"/utf8>> | Input@6] ->
- parse_hex(Input@6, (Number * 16) + 4, Sign);
-
- [<<"5"/utf8>> | Input@7] ->
- parse_hex(Input@7, (Number * 16) + 5, Sign);
-
- [<<"6"/utf8>> | Input@8] ->
- parse_hex(Input@8, (Number * 16) + 6, Sign);
-
- [<<"7"/utf8>> | Input@9] ->
- parse_hex(Input@9, (Number * 16) + 7, Sign);
-
- [<<"8"/utf8>> | Input@10] ->
- parse_hex(Input@10, (Number * 16) + 8, Sign);
-
- [<<"9"/utf8>> | Input@11] ->
- parse_hex(Input@11, (Number * 16) + 9, Sign);
-
- [<<"a"/utf8>> | Input@12] ->
- parse_hex(Input@12, (Number * 16) + 10, Sign);
-
- [<<"b"/utf8>> | Input@13] ->
- parse_hex(Input@13, (Number * 16) + 11, Sign);
-
- [<<"c"/utf8>> | Input@14] ->
- parse_hex(Input@14, (Number * 16) + 12, Sign);
-
- [<<"d"/utf8>> | Input@15] ->
- parse_hex(Input@15, (Number * 16) + 13, Sign);
-
- [<<"e"/utf8>> | Input@16] ->
- parse_hex(Input@16, (Number * 16) + 14, Sign);
-
- [<<"f"/utf8>> | Input@17] ->
- parse_hex(Input@17, (Number * 16) + 15, Sign);
-
- [<<"A"/utf8>> | Input@18] ->
- parse_hex(Input@18, (Number * 16) + 10, Sign);
-
- [<<"B"/utf8>> | Input@19] ->
- parse_hex(Input@19, (Number * 16) + 11, Sign);
-
- [<<"C"/utf8>> | Input@20] ->
- parse_hex(Input@20, (Number * 16) + 12, Sign);
-
- [<<"D"/utf8>> | Input@21] ->
- parse_hex(Input@21, (Number * 16) + 13, Sign);
-
- [<<"E"/utf8>> | Input@22] ->
- parse_hex(Input@22, (Number * 16) + 14, Sign);
-
- [<<"F"/utf8>> | Input@23] ->
- parse_hex(Input@23, (Number * 16) + 15, Sign);
-
- Input@24 ->
- Number@1 = case Sign of
- positive ->
- Number;
-
- negative ->
- - Number
- end,
- {ok, {{int, Number@1}, Input@24}}
- end.
-
--spec parse_octal(list(binary()), integer(), sign()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_octal(Input, Number, Sign) ->
- case Input of
- [<<"_"/utf8>> | Input@1] ->
- parse_octal(Input@1, Number, Sign);
-
- [<<"0"/utf8>> | Input@2] ->
- parse_octal(Input@2, (Number * 8) + 0, Sign);
-
- [<<"1"/utf8>> | Input@3] ->
- parse_octal(Input@3, (Number * 8) + 1, Sign);
-
- [<<"2"/utf8>> | Input@4] ->
- parse_octal(Input@4, (Number * 8) + 2, Sign);
-
- [<<"3"/utf8>> | Input@5] ->
- parse_octal(Input@5, (Number * 8) + 3, Sign);
-
- [<<"4"/utf8>> | Input@6] ->
- parse_octal(Input@6, (Number * 8) + 4, Sign);
-
- [<<"5"/utf8>> | Input@7] ->
- parse_octal(Input@7, (Number * 8) + 5, Sign);
-
- [<<"6"/utf8>> | Input@8] ->
- parse_octal(Input@8, (Number * 8) + 6, Sign);
-
- [<<"7"/utf8>> | Input@9] ->
- parse_octal(Input@9, (Number * 8) + 7, Sign);
-
- Input@10 ->
- Number@1 = case Sign of
- positive ->
- Number;
-
- negative ->
- - Number
- end,
- {ok, {{int, Number@1}, Input@10}}
- end.
-
--spec parse_binary(list(binary()), integer(), sign()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_binary(Input, Number, Sign) ->
- case Input of
- [<<"_"/utf8>> | Input@1] ->
- parse_binary(Input@1, Number, Sign);
-
- [<<"0"/utf8>> | Input@2] ->
- parse_binary(Input@2, (Number * 2) + 0, Sign);
-
- [<<"1"/utf8>> | Input@3] ->
- parse_binary(Input@3, (Number * 2) + 1, Sign);
-
- Input@4 ->
- Number@1 = case Sign of
- positive ->
- Number;
-
- negative ->
- - Number
- end,
- {ok, {{int, Number@1}, Input@4}}
- end.
-
--spec parse_exponent(list(binary()), float(), sign(), integer(), sign()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_exponent(Input, N, N_sign, Ex, Ex_sign) ->
- case Input of
- [<<"_"/utf8>> | Input@1] ->
- parse_exponent(Input@1, N, N_sign, Ex, Ex_sign);
-
- [<<"0"/utf8>> | Input@2] ->
- parse_exponent(Input@2, N, N_sign, Ex * 10, Ex_sign);
-
- [<<"1"/utf8>> | Input@3] ->
- parse_exponent(Input@3, N, N_sign, (Ex * 10) + 1, Ex_sign);
-
- [<<"2"/utf8>> | Input@4] ->
- parse_exponent(Input@4, N, N_sign, (Ex * 10) + 2, Ex_sign);
-
- [<<"3"/utf8>> | Input@5] ->
- parse_exponent(Input@5, N, N_sign, (Ex * 10) + 3, Ex_sign);
-
- [<<"4"/utf8>> | Input@6] ->
- parse_exponent(Input@6, N, N_sign, (Ex * 10) + 4, Ex_sign);
-
- [<<"5"/utf8>> | Input@7] ->
- parse_exponent(Input@7, N, N_sign, (Ex * 10) + 5, Ex_sign);
-
- [<<"6"/utf8>> | Input@8] ->
- parse_exponent(Input@8, N, N_sign, (Ex * 10) + 6, Ex_sign);
-
- [<<"7"/utf8>> | Input@9] ->
- parse_exponent(Input@9, N, N_sign, (Ex * 10) + 7, Ex_sign);
-
- [<<"8"/utf8>> | Input@10] ->
- parse_exponent(Input@10, N, N_sign, (Ex * 10) + 8, Ex_sign);
-
- [<<"9"/utf8>> | Input@11] ->
- parse_exponent(Input@11, N, N_sign, (Ex * 10) + 9, Ex_sign);
-
- Input@12 ->
- Number = case N_sign of
- positive ->
- N;
-
- negative ->
- N * -1.0
- end,
- Exponent = gleam@int:to_float(case Ex_sign of
- positive ->
- Ex;
-
- negative ->
- - Ex
- end),
- Multiplier@1 = case gleam@float:power(10.0, Exponent) of
- {ok, Multiplier} ->
- Multiplier;
-
- {error, _} ->
- 1.0
- end,
- {ok, {{float, Number * Multiplier@1}, Input@12}}
- end.
-
--spec parse_float(list(binary()), float(), sign(), float()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_float(Input, Number, Sign, Unit) ->
- case Input of
- [<<"_"/utf8>> | Input@1] ->
- parse_float(Input@1, Number, Sign, Unit);
-
- [<<"0"/utf8>> | Input@2] ->
- parse_float(Input@2, Number, Sign, Unit * 0.1);
-
- [<<"1"/utf8>> | Input@3] ->
- parse_float(Input@3, Number + (1.0 * Unit), Sign, Unit * 0.1);
-
- [<<"2"/utf8>> | Input@4] ->
- parse_float(Input@4, Number + (2.0 * Unit), Sign, Unit * 0.1);
-
- [<<"3"/utf8>> | Input@5] ->
- parse_float(Input@5, Number + (3.0 * Unit), Sign, Unit * 0.1);
-
- [<<"4"/utf8>> | Input@6] ->
- parse_float(Input@6, Number + (4.0 * Unit), Sign, Unit * 0.1);
-
- [<<"5"/utf8>> | Input@7] ->
- parse_float(Input@7, Number + (5.0 * Unit), Sign, Unit * 0.1);
-
- [<<"6"/utf8>> | Input@8] ->
- parse_float(Input@8, Number + (6.0 * Unit), Sign, Unit * 0.1);
-
- [<<"7"/utf8>> | Input@9] ->
- parse_float(Input@9, Number + (7.0 * Unit), Sign, Unit * 0.1);
-
- [<<"8"/utf8>> | Input@10] ->
- parse_float(Input@10, Number + (8.0 * Unit), Sign, Unit * 0.1);
-
- [<<"9"/utf8>> | Input@11] ->
- parse_float(Input@11, Number + (9.0 * Unit), Sign, Unit * 0.1);
-
- [<<"e"/utf8>>, <<"+"/utf8>> | Input@12] ->
- parse_exponent(Input@12, Number, Sign, 0, positive);
-
- [<<"e"/utf8>>, <<"-"/utf8>> | Input@13] ->
- parse_exponent(Input@13, Number, Sign, 0, negative);
-
- [<<"e"/utf8>> | Input@14] ->
- parse_exponent(Input@14, Number, Sign, 0, positive);
-
- [<<"E"/utf8>>, <<"+"/utf8>> | Input@15] ->
- parse_exponent(Input@15, Number, Sign, 0, positive);
-
- [<<"E"/utf8>>, <<"-"/utf8>> | Input@16] ->
- parse_exponent(Input@16, Number, Sign, 0, negative);
-
- [<<"E"/utf8>> | Input@17] ->
- parse_exponent(Input@17, Number, Sign, 0, positive);
-
- Input@18 ->
- Number@1 = case Sign of
- positive ->
- Number;
-
- negative ->
- Number * -1.0
- end,
- {ok, {{float, Number@1}, Input@18}}
- end.
-
--spec parse_string(list(binary()), binary()) -> {ok, {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_string(Input, String) ->
- case Input of
- [<<"\""/utf8>> | Input@1] ->
- {ok, {{string, String}, Input@1}};
-
- [<<"\\"/utf8>>, <<"t"/utf8>> | Input@2] ->
- parse_string(Input@2, <<String/binary, "\t"/utf8>>);
-
- [<<"\\"/utf8>>, <<"n"/utf8>> | Input@3] ->
- parse_string(Input@3, <<String/binary, "\n"/utf8>>);
-
- [<<"\\"/utf8>>, <<"r"/utf8>> | Input@4] ->
- parse_string(Input@4, <<String/binary, "\r"/utf8>>);
-
- [<<"\\"/utf8>>, <<"\""/utf8>> | Input@5] ->
- parse_string(Input@5, <<String/binary, "\""/utf8>>);
-
- [<<"\\"/utf8>>, <<"\\"/utf8>> | Input@6] ->
- parse_string(Input@6, <<String/binary, "\\"/utf8>>);
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}};
-
- [<<"\n"/utf8>> | _] ->
- {error, {unexpected, <<"\n"/utf8>>, <<"\""/utf8>>}};
-
- [<<"\r\n"/utf8>> | _] ->
- {error, {unexpected, <<"\r\n"/utf8>>, <<"\""/utf8>>}};
-
- [G | Input@7] ->
- parse_string(Input@7, <<String/binary, G/binary>>)
- end.
-
--spec parse_multi_line_string(list(binary()), binary()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_multi_line_string(Input, String) ->
- case Input of
- [<<"\""/utf8>>, <<"\""/utf8>>, <<"\""/utf8>> | Input@1] ->
- {ok, {{string, String}, Input@1}};
-
- [<<"\\"/utf8>>, <<"\n"/utf8>> | Input@2] ->
- parse_multi_line_string(skip_whitespace(Input@2), String);
-
- [<<"\\"/utf8>>, <<"\r\n"/utf8>> | Input@3] ->
- parse_multi_line_string(skip_whitespace(Input@3), String);
-
- [<<"\r\n"/utf8>> | Input@4] when String =:= <<""/utf8>> ->
- parse_multi_line_string(Input@4, String);
-
- [<<"\n"/utf8>> | Input@5] when String =:= <<""/utf8>> ->
- parse_multi_line_string(Input@5, String);
-
- [<<"\r\n"/utf8>> | Input@6] when String =:= <<""/utf8>> ->
- parse_multi_line_string(Input@6, String);
-
- [<<"\\"/utf8>>, <<"t"/utf8>> | Input@7] ->
- parse_multi_line_string(Input@7, <<String/binary, "\t"/utf8>>);
-
- [<<"\\"/utf8>>, <<"n"/utf8>> | Input@8] ->
- parse_multi_line_string(Input@8, <<String/binary, "\n"/utf8>>);
-
- [<<"\\"/utf8>>, <<"r"/utf8>> | Input@9] ->
- parse_multi_line_string(Input@9, <<String/binary, "\r"/utf8>>);
-
- [<<"\\"/utf8>>, <<"\""/utf8>> | Input@10] ->
- parse_multi_line_string(Input@10, <<String/binary, "\""/utf8>>);
-
- [<<"\\"/utf8>>, <<"\\"/utf8>> | Input@11] ->
- parse_multi_line_string(Input@11, <<String/binary, "\\"/utf8>>);
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}};
-
- [G | Input@12] ->
- parse_multi_line_string(Input@12, <<String/binary, G/binary>>)
- end.
-
--spec parse_multi_line_literal_string(list(binary()), binary()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_multi_line_literal_string(Input, String) ->
- case Input of
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}};
-
- [<<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>> | _] ->
- {error, {unexpected, <<"''''"/utf8>>, <<"'''"/utf8>>}};
-
- [<<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>> | Input@1] ->
- {ok, {{string, String}, Input@1}};
-
- [<<"\n"/utf8>> | Input@2] when String =:= <<""/utf8>> ->
- parse_multi_line_literal_string(Input@2, String);
-
- [<<"\r\n"/utf8>> | Input@3] when String =:= <<""/utf8>> ->
- parse_multi_line_literal_string(Input@3, String);
-
- [G | Input@4] ->
- parse_multi_line_literal_string(
- Input@4,
- <<String/binary, G/binary>>
- )
- end.
-
--spec parse_literal_string(list(binary()), binary()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_literal_string(Input, String) ->
- case Input of
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}};
-
- [<<"\n"/utf8>> | _] ->
- {error, {unexpected, <<"\n"/utf8>>, <<"'"/utf8>>}};
-
- [<<"\r\n"/utf8>> | _] ->
- {error, {unexpected, <<"\r\n"/utf8>>, <<"'"/utf8>>}};
-
- [<<"'"/utf8>> | Input@1] ->
- {ok, {{string, String}, Input@1}};
-
- [G | Input@2] ->
- parse_literal_string(Input@2, <<String/binary, G/binary>>)
- end.
-
--spec parse_time_ms(list(binary()), integer(), integer()) -> {ok,
- {{integer(), integer()}, list(binary())}} |
- {error, parse_error()}.
-parse_time_ms(Input, Seconds, Ms) ->
- case Input of
- [<<"0"/utf8>> | Input@1] when Ms < 100000 ->
- parse_time_ms(Input@1, Seconds, (Ms * 10) + 0);
-
- [<<"1"/utf8>> | Input@2] when Ms < 100000 ->
- parse_time_ms(Input@2, Seconds, (Ms * 10) + 1);
-
- [<<"2"/utf8>> | Input@3] when Ms < 100000 ->
- parse_time_ms(Input@3, Seconds, (Ms * 10) + 2);
-
- [<<"3"/utf8>> | Input@4] when Ms < 100000 ->
- parse_time_ms(Input@4, Seconds, (Ms * 10) + 3);
-
- [<<"4"/utf8>> | Input@5] when Ms < 100000 ->
- parse_time_ms(Input@5, Seconds, (Ms * 10) + 4);
-
- [<<"5"/utf8>> | Input@6] when Ms < 100000 ->
- parse_time_ms(Input@6, Seconds, (Ms * 10) + 5);
-
- [<<"6"/utf8>> | Input@7] when Ms < 100000 ->
- parse_time_ms(Input@7, Seconds, (Ms * 10) + 6);
-
- [<<"7"/utf8>> | Input@8] when Ms < 100000 ->
- parse_time_ms(Input@8, Seconds, (Ms * 10) + 7);
-
- [<<"8"/utf8>> | Input@9] when Ms < 100000 ->
- parse_time_ms(Input@9, Seconds, (Ms * 10) + 8);
-
- [<<"9"/utf8>> | Input@10] when Ms < 100000 ->
- parse_time_ms(Input@10, Seconds, (Ms * 10) + 9);
-
- _ ->
- {ok, {{Seconds, Ms}, Input}}
- end.
-
--spec parse_number_under_60(list(binary()), binary()) -> {ok,
- {integer(), list(binary())}} |
- {error, parse_error()}.
-parse_number_under_60(Input, Expected) ->
- case Input of
- [<<"0"/utf8>>, <<"0"/utf8>> | Input@1] ->
- {ok, {0, Input@1}};
-
- [<<"0"/utf8>>, <<"1"/utf8>> | Input@2] ->
- {ok, {1, Input@2}};
-
- [<<"0"/utf8>>, <<"2"/utf8>> | Input@3] ->
- {ok, {2, Input@3}};
-
- [<<"0"/utf8>>, <<"3"/utf8>> | Input@4] ->
- {ok, {3, Input@4}};
-
- [<<"0"/utf8>>, <<"4"/utf8>> | Input@5] ->
- {ok, {4, Input@5}};
-
- [<<"0"/utf8>>, <<"5"/utf8>> | Input@6] ->
- {ok, {5, Input@6}};
-
- [<<"0"/utf8>>, <<"6"/utf8>> | Input@7] ->
- {ok, {6, Input@7}};
-
- [<<"0"/utf8>>, <<"7"/utf8>> | Input@8] ->
- {ok, {7, Input@8}};
-
- [<<"0"/utf8>>, <<"8"/utf8>> | Input@9] ->
- {ok, {8, Input@9}};
-
- [<<"0"/utf8>>, <<"9"/utf8>> | Input@10] ->
- {ok, {9, Input@10}};
-
- [<<"1"/utf8>>, <<"0"/utf8>> | Input@11] ->
- {ok, {10, Input@11}};
-
- [<<"1"/utf8>>, <<"1"/utf8>> | Input@12] ->
- {ok, {11, Input@12}};
-
- [<<"1"/utf8>>, <<"2"/utf8>> | Input@13] ->
- {ok, {12, Input@13}};
-
- [<<"1"/utf8>>, <<"3"/utf8>> | Input@14] ->
- {ok, {13, Input@14}};
-
- [<<"1"/utf8>>, <<"4"/utf8>> | Input@15] ->
- {ok, {14, Input@15}};
-
- [<<"1"/utf8>>, <<"5"/utf8>> | Input@16] ->
- {ok, {15, Input@16}};
-
- [<<"1"/utf8>>, <<"6"/utf8>> | Input@17] ->
- {ok, {16, Input@17}};
-
- [<<"1"/utf8>>, <<"7"/utf8>> | Input@18] ->
- {ok, {17, Input@18}};
-
- [<<"1"/utf8>>, <<"8"/utf8>> | Input@19] ->
- {ok, {18, Input@19}};
-
- [<<"1"/utf8>>, <<"9"/utf8>> | Input@20] ->
- {ok, {19, Input@20}};
-
- [<<"2"/utf8>>, <<"0"/utf8>> | Input@21] ->
- {ok, {20, Input@21}};
-
- [<<"2"/utf8>>, <<"1"/utf8>> | Input@22] ->
- {ok, {21, Input@22}};
-
- [<<"2"/utf8>>, <<"2"/utf8>> | Input@23] ->
- {ok, {22, Input@23}};
-
- [<<"2"/utf8>>, <<"3"/utf8>> | Input@24] ->
- {ok, {23, Input@24}};
-
- [<<"2"/utf8>>, <<"4"/utf8>> | Input@25] ->
- {ok, {24, Input@25}};
-
- [<<"2"/utf8>>, <<"5"/utf8>> | Input@26] ->
- {ok, {25, Input@26}};
-
- [<<"2"/utf8>>, <<"6"/utf8>> | Input@27] ->
- {ok, {26, Input@27}};
-
- [<<"2"/utf8>>, <<"7"/utf8>> | Input@28] ->
- {ok, {27, Input@28}};
-
- [<<"2"/utf8>>, <<"8"/utf8>> | Input@29] ->
- {ok, {28, Input@29}};
-
- [<<"2"/utf8>>, <<"9"/utf8>> | Input@30] ->
- {ok, {29, Input@30}};
-
- [<<"3"/utf8>>, <<"0"/utf8>> | Input@31] ->
- {ok, {30, Input@31}};
-
- [<<"3"/utf8>>, <<"1"/utf8>> | Input@32] ->
- {ok, {31, Input@32}};
-
- [<<"3"/utf8>>, <<"2"/utf8>> | Input@33] ->
- {ok, {32, Input@33}};
-
- [<<"3"/utf8>>, <<"3"/utf8>> | Input@34] ->
- {ok, {33, Input@34}};
-
- [<<"3"/utf8>>, <<"4"/utf8>> | Input@35] ->
- {ok, {34, Input@35}};
-
- [<<"3"/utf8>>, <<"5"/utf8>> | Input@36] ->
- {ok, {35, Input@36}};
-
- [<<"3"/utf8>>, <<"6"/utf8>> | Input@37] ->
- {ok, {36, Input@37}};
-
- [<<"3"/utf8>>, <<"7"/utf8>> | Input@38] ->
- {ok, {37, Input@38}};
-
- [<<"3"/utf8>>, <<"8"/utf8>> | Input@39] ->
- {ok, {38, Input@39}};
-
- [<<"3"/utf8>>, <<"9"/utf8>> | Input@40] ->
- {ok, {39, Input@40}};
-
- [<<"4"/utf8>>, <<"0"/utf8>> | Input@41] ->
- {ok, {40, Input@41}};
-
- [<<"4"/utf8>>, <<"1"/utf8>> | Input@42] ->
- {ok, {41, Input@42}};
-
- [<<"4"/utf8>>, <<"2"/utf8>> | Input@43] ->
- {ok, {42, Input@43}};
-
- [<<"4"/utf8>>, <<"3"/utf8>> | Input@44] ->
- {ok, {43, Input@44}};
-
- [<<"4"/utf8>>, <<"4"/utf8>> | Input@45] ->
- {ok, {44, Input@45}};
-
- [<<"4"/utf8>>, <<"5"/utf8>> | Input@46] ->
- {ok, {45, Input@46}};
-
- [<<"4"/utf8>>, <<"6"/utf8>> | Input@47] ->
- {ok, {46, Input@47}};
-
- [<<"4"/utf8>>, <<"7"/utf8>> | Input@48] ->
- {ok, {47, Input@48}};
-
- [<<"4"/utf8>>, <<"8"/utf8>> | Input@49] ->
- {ok, {48, Input@49}};
-
- [<<"4"/utf8>>, <<"9"/utf8>> | Input@50] ->
- {ok, {49, Input@50}};
-
- [<<"5"/utf8>>, <<"0"/utf8>> | Input@51] ->
- {ok, {50, Input@51}};
-
- [<<"5"/utf8>>, <<"1"/utf8>> | Input@52] ->
- {ok, {51, Input@52}};
-
- [<<"5"/utf8>>, <<"2"/utf8>> | Input@53] ->
- {ok, {52, Input@53}};
-
- [<<"5"/utf8>>, <<"3"/utf8>> | Input@54] ->
- {ok, {53, Input@54}};
-
- [<<"5"/utf8>>, <<"4"/utf8>> | Input@55] ->
- {ok, {54, Input@55}};
-
- [<<"5"/utf8>>, <<"5"/utf8>> | Input@56] ->
- {ok, {55, Input@56}};
-
- [<<"5"/utf8>>, <<"6"/utf8>> | Input@57] ->
- {ok, {56, Input@57}};
-
- [<<"5"/utf8>>, <<"7"/utf8>> | Input@58] ->
- {ok, {57, Input@58}};
-
- [<<"5"/utf8>>, <<"8"/utf8>> | Input@59] ->
- {ok, {58, Input@59}};
-
- [<<"5"/utf8>>, <<"9"/utf8>> | Input@60] ->
- {ok, {59, Input@60}};
-
- [G | _] ->
- {error, {unexpected, G, Expected}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, Expected}}
- end.
-
--spec parse_hour_minute(list(binary())) -> {ok,
- {{integer(), integer()}, list(binary())}} |
- {error, parse_error()}.
-parse_hour_minute(Input) ->
- do(case Input of
- [<<"0"/utf8>>, <<"0"/utf8>>, <<":"/utf8>> | Input@1] ->
- {ok, {0, Input@1}};
-
- [<<"0"/utf8>>, <<"1"/utf8>>, <<":"/utf8>> | Input@2] ->
- {ok, {1, Input@2}};
-
- [<<"0"/utf8>>, <<"2"/utf8>>, <<":"/utf8>> | Input@3] ->
- {ok, {2, Input@3}};
-
- [<<"0"/utf8>>, <<"3"/utf8>>, <<":"/utf8>> | Input@4] ->
- {ok, {3, Input@4}};
-
- [<<"0"/utf8>>, <<"4"/utf8>>, <<":"/utf8>> | Input@5] ->
- {ok, {4, Input@5}};
-
- [<<"0"/utf8>>, <<"5"/utf8>>, <<":"/utf8>> | Input@6] ->
- {ok, {5, Input@6}};
-
- [<<"0"/utf8>>, <<"6"/utf8>>, <<":"/utf8>> | Input@7] ->
- {ok, {6, Input@7}};
-
- [<<"0"/utf8>>, <<"7"/utf8>>, <<":"/utf8>> | Input@8] ->
- {ok, {7, Input@8}};
-
- [<<"0"/utf8>>, <<"8"/utf8>>, <<":"/utf8>> | Input@9] ->
- {ok, {8, Input@9}};
-
- [<<"0"/utf8>>, <<"9"/utf8>>, <<":"/utf8>> | Input@10] ->
- {ok, {9, Input@10}};
-
- [<<"1"/utf8>>, <<"0"/utf8>>, <<":"/utf8>> | Input@11] ->
- {ok, {10, Input@11}};
-
- [<<"1"/utf8>>, <<"1"/utf8>>, <<":"/utf8>> | Input@12] ->
- {ok, {11, Input@12}};
-
- [<<"1"/utf8>>, <<"2"/utf8>>, <<":"/utf8>> | Input@13] ->
- {ok, {12, Input@13}};
-
- [<<"1"/utf8>>, <<"3"/utf8>>, <<":"/utf8>> | Input@14] ->
- {ok, {13, Input@14}};
-
- [<<"1"/utf8>>, <<"4"/utf8>>, <<":"/utf8>> | Input@15] ->
- {ok, {14, Input@15}};
-
- [<<"1"/utf8>>, <<"5"/utf8>>, <<":"/utf8>> | Input@16] ->
- {ok, {15, Input@16}};
-
- [<<"1"/utf8>>, <<"6"/utf8>>, <<":"/utf8>> | Input@17] ->
- {ok, {16, Input@17}};
-
- [<<"1"/utf8>>, <<"7"/utf8>>, <<":"/utf8>> | Input@18] ->
- {ok, {17, Input@18}};
-
- [<<"1"/utf8>>, <<"8"/utf8>>, <<":"/utf8>> | Input@19] ->
- {ok, {18, Input@19}};
-
- [<<"1"/utf8>>, <<"9"/utf8>>, <<":"/utf8>> | Input@20] ->
- {ok, {19, Input@20}};
-
- [<<"2"/utf8>>, <<"0"/utf8>>, <<":"/utf8>> | Input@21] ->
- {ok, {20, Input@21}};
-
- [<<"2"/utf8>>, <<"1"/utf8>>, <<":"/utf8>> | Input@22] ->
- {ok, {21, Input@22}};
-
- [<<"2"/utf8>>, <<"2"/utf8>>, <<":"/utf8>> | Input@23] ->
- {ok, {22, Input@23}};
-
- [<<"2"/utf8>>, <<"3"/utf8>>, <<":"/utf8>> | Input@24] ->
- {ok, {23, Input@24}};
-
- [G | _] ->
- {error, {unexpected, G, <<"time"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"time"/utf8>>}}
- end, fun(Hours, Input@25) ->
- do(
- parse_number_under_60(Input@25, <<"minutes"/utf8>>),
- fun(Minutes, Input@26) -> {ok, {{Hours, Minutes}, Input@26}} end
- )
- end).
-
--spec parse_time_s_ms(list(binary())) -> {ok,
- {{integer(), integer()}, list(binary())}} |
- {error, parse_error()}.
-parse_time_s_ms(Input) ->
- case Input of
- [<<":"/utf8>> | Input@1] ->
- do(
- parse_number_under_60(Input@1, <<"seconds"/utf8>>),
- fun(Seconds, Input@2) -> case Input@2 of
- [<<"."/utf8>> | Input@3] ->
- parse_time_ms(Input@3, Seconds, 0);
-
- _ ->
- {ok, {{Seconds, 0}, Input@2}}
- end end
- );
-
- _ ->
- {ok, {{0, 0}, Input}}
- end.
-
--spec parse_time_minute(list(binary()), integer()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_time_minute(Input, Hours) ->
- do(
- parse_number_under_60(Input, <<"minutes"/utf8>>),
- fun(Minutes, Input@1) ->
- do(
- parse_time_s_ms(Input@1),
- fun(_use0, Input@2) ->
- {Seconds, Ms} = _use0,
- Time = {time_value, Hours, Minutes, Seconds, Ms},
- {ok, {{time, Time}, Input@2}}
- end
- )
- end
- ).
-
--spec parse_time_value(list(binary())) -> {ok, {time(), list(binary())}} |
- {error, parse_error()}.
-parse_time_value(Input) ->
- do(
- parse_hour_minute(Input),
- fun(_use0, Input@1) ->
- {Hours, Minutes} = _use0,
- do(
- parse_time_s_ms(Input@1),
- fun(_use0@1, Input@2) ->
- {Seconds, Ms} = _use0@1,
- Time = {time_value, Hours, Minutes, Seconds, Ms},
- {ok, {Time, Input@2}}
- end
- )
- end
- ).
-
--spec parse_offset_hours(list(binary()), sign()) -> {ok,
- {offset(), list(binary())}} |
- {error, parse_error()}.
-parse_offset_hours(Input, Sign) ->
- do(
- parse_hour_minute(Input),
- fun(_use0, Input@1) ->
- {Hours, Minutes} = _use0,
- {ok, {{offset, Sign, Hours, Minutes}, Input@1}}
- end
- ).
-
--spec parse_offset(list(binary())) -> {ok, {offset(), list(binary())}} |
- {error, parse_error()}.
-parse_offset(Input) ->
- case Input of
- [<<"Z"/utf8>> | Input@1] ->
- {ok, {{offset, positive, 0, 0}, Input@1}};
-
- [<<"+"/utf8>> | Input@2] ->
- parse_offset_hours(Input@2, positive);
-
- [<<"-"/utf8>> | Input@3] ->
- parse_offset_hours(Input@3, negative);
-
- _ ->
- {ok, {local, Input}}
- end.
-
--spec parse_date_end(list(binary()), integer(), integer(), integer()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_date_end(Input, Year, Month, Day) ->
- Date = {date_value, Year, Month, Day},
- case Input of
- [<<" "/utf8>> | Input@1] ->
- do(
- parse_time_value(Input@1),
- fun(Time, Input@2) ->
- do(
- parse_offset(Input@2),
- fun(Offset, Input@3) ->
- {ok,
- {{date_time,
- {date_time_value, Date, Time, Offset}},
- Input@3}}
- end
- )
- end
- );
-
- [<<"T"/utf8>> | Input@1] ->
- do(
- parse_time_value(Input@1),
- fun(Time, Input@2) ->
- do(
- parse_offset(Input@2),
- fun(Offset, Input@3) ->
- {ok,
- {{date_time,
- {date_time_value, Date, Time, Offset}},
- Input@3}}
- end
- )
- end
- );
-
- _ ->
- {ok, {{date, Date}, Input}}
- end.
-
--spec parse_date_day(list(binary()), integer(), integer()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_date_day(Input, Year, Month) ->
- case Input of
- [<<"0"/utf8>>, <<"1"/utf8>> | Input@1] ->
- parse_date_end(Input@1, Year, Month, 1);
-
- [<<"0"/utf8>>, <<"2"/utf8>> | Input@2] ->
- parse_date_end(Input@2, Year, Month, 2);
-
- [<<"0"/utf8>>, <<"3"/utf8>> | Input@3] ->
- parse_date_end(Input@3, Year, Month, 3);
-
- [<<"0"/utf8>>, <<"4"/utf8>> | Input@4] ->
- parse_date_end(Input@4, Year, Month, 4);
-
- [<<"0"/utf8>>, <<"5"/utf8>> | Input@5] ->
- parse_date_end(Input@5, Year, Month, 5);
-
- [<<"0"/utf8>>, <<"6"/utf8>> | Input@6] ->
- parse_date_end(Input@6, Year, Month, 6);
-
- [<<"0"/utf8>>, <<"7"/utf8>> | Input@7] ->
- parse_date_end(Input@7, Year, Month, 7);
-
- [<<"0"/utf8>>, <<"8"/utf8>> | Input@8] ->
- parse_date_end(Input@8, Year, Month, 8);
-
- [<<"0"/utf8>>, <<"9"/utf8>> | Input@9] ->
- parse_date_end(Input@9, Year, Month, 9);
-
- [<<"1"/utf8>>, <<"0"/utf8>> | Input@10] ->
- parse_date_end(Input@10, Year, Month, 10);
-
- [<<"1"/utf8>>, <<"1"/utf8>> | Input@11] ->
- parse_date_end(Input@11, Year, Month, 11);
-
- [<<"1"/utf8>>, <<"2"/utf8>> | Input@12] ->
- parse_date_end(Input@12, Year, Month, 12);
-
- [<<"1"/utf8>>, <<"3"/utf8>> | Input@13] ->
- parse_date_end(Input@13, Year, Month, 13);
-
- [<<"1"/utf8>>, <<"4"/utf8>> | Input@14] ->
- parse_date_end(Input@14, Year, Month, 14);
-
- [<<"1"/utf8>>, <<"5"/utf8>> | Input@15] ->
- parse_date_end(Input@15, Year, Month, 15);
-
- [<<"1"/utf8>>, <<"6"/utf8>> | Input@16] ->
- parse_date_end(Input@16, Year, Month, 16);
-
- [<<"1"/utf8>>, <<"7"/utf8>> | Input@17] ->
- parse_date_end(Input@17, Year, Month, 17);
-
- [<<"1"/utf8>>, <<"8"/utf8>> | Input@18] ->
- parse_date_end(Input@18, Year, Month, 18);
-
- [<<"1"/utf8>>, <<"9"/utf8>> | Input@19] ->
- parse_date_end(Input@19, Year, Month, 19);
-
- [<<"2"/utf8>>, <<"0"/utf8>> | Input@20] ->
- parse_date_end(Input@20, Year, Month, 20);
-
- [<<"2"/utf8>>, <<"1"/utf8>> | Input@21] ->
- parse_date_end(Input@21, Year, Month, 21);
-
- [<<"2"/utf8>>, <<"2"/utf8>> | Input@22] ->
- parse_date_end(Input@22, Year, Month, 22);
-
- [<<"2"/utf8>>, <<"3"/utf8>> | Input@23] ->
- parse_date_end(Input@23, Year, Month, 23);
-
- [<<"2"/utf8>>, <<"4"/utf8>> | Input@24] ->
- parse_date_end(Input@24, Year, Month, 24);
-
- [<<"2"/utf8>>, <<"5"/utf8>> | Input@25] ->
- parse_date_end(Input@25, Year, Month, 25);
-
- [<<"2"/utf8>>, <<"6"/utf8>> | Input@26] ->
- parse_date_end(Input@26, Year, Month, 26);
-
- [<<"2"/utf8>>, <<"7"/utf8>> | Input@27] ->
- parse_date_end(Input@27, Year, Month, 27);
-
- [<<"2"/utf8>>, <<"8"/utf8>> | Input@28] ->
- parse_date_end(Input@28, Year, Month, 28);
-
- [<<"2"/utf8>>, <<"9"/utf8>> | Input@29] ->
- parse_date_end(Input@29, Year, Month, 29);
-
- [<<"3"/utf8>>, <<"0"/utf8>> | Input@30] ->
- parse_date_end(Input@30, Year, Month, 30);
-
- [<<"3"/utf8>>, <<"1"/utf8>> | Input@31] ->
- parse_date_end(Input@31, Year, Month, 31);
-
- [G | _] ->
- {error, {unexpected, G, <<"date day"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"date day"/utf8>>}}
- end.
-
--spec parse_date(list(binary()), integer()) -> {ok, {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_date(Input, Year) ->
- case Input of
- [<<"0"/utf8>>, <<"1"/utf8>>, <<"-"/utf8>> | Input@1] ->
- parse_date_day(Input@1, Year, 1);
-
- [<<"0"/utf8>>, <<"2"/utf8>>, <<"-"/utf8>> | Input@2] ->
- parse_date_day(Input@2, Year, 2);
-
- [<<"0"/utf8>>, <<"3"/utf8>>, <<"-"/utf8>> | Input@3] ->
- parse_date_day(Input@3, Year, 3);
-
- [<<"0"/utf8>>, <<"4"/utf8>>, <<"-"/utf8>> | Input@4] ->
- parse_date_day(Input@4, Year, 4);
-
- [<<"0"/utf8>>, <<"5"/utf8>>, <<"-"/utf8>> | Input@5] ->
- parse_date_day(Input@5, Year, 5);
-
- [<<"0"/utf8>>, <<"6"/utf8>>, <<"-"/utf8>> | Input@6] ->
- parse_date_day(Input@6, Year, 6);
-
- [<<"0"/utf8>>, <<"7"/utf8>>, <<"-"/utf8>> | Input@7] ->
- parse_date_day(Input@7, Year, 7);
-
- [<<"0"/utf8>>, <<"8"/utf8>>, <<"-"/utf8>> | Input@8] ->
- parse_date_day(Input@8, Year, 8);
-
- [<<"0"/utf8>>, <<"9"/utf8>>, <<"-"/utf8>> | Input@9] ->
- parse_date_day(Input@9, Year, 9);
-
- [<<"1"/utf8>>, <<"0"/utf8>>, <<"-"/utf8>> | Input@10] ->
- parse_date_day(Input@10, Year, 10);
-
- [<<"1"/utf8>>, <<"1"/utf8>>, <<"-"/utf8>> | Input@11] ->
- parse_date_day(Input@11, Year, 11);
-
- [<<"1"/utf8>>, <<"2"/utf8>>, <<"-"/utf8>> | Input@12] ->
- parse_date_day(Input@12, Year, 12);
-
- [G | _] ->
- {error, {unexpected, G, <<"date month"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"date month"/utf8>>}}
- end.
-
--spec parse_number(list(binary()), integer(), sign()) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_number(Input, Number, Sign) ->
- case Input of
- [<<"_"/utf8>> | Input@1] ->
- parse_number(Input@1, Number, Sign);
-
- [<<"0"/utf8>> | Input@2] ->
- parse_number(Input@2, (Number * 10) + 0, Sign);
-
- [<<"1"/utf8>> | Input@3] ->
- parse_number(Input@3, (Number * 10) + 1, Sign);
-
- [<<"2"/utf8>> | Input@4] ->
- parse_number(Input@4, (Number * 10) + 2, Sign);
-
- [<<"3"/utf8>> | Input@5] ->
- parse_number(Input@5, (Number * 10) + 3, Sign);
-
- [<<"4"/utf8>> | Input@6] ->
- parse_number(Input@6, (Number * 10) + 4, Sign);
-
- [<<"5"/utf8>> | Input@7] ->
- parse_number(Input@7, (Number * 10) + 5, Sign);
-
- [<<"6"/utf8>> | Input@8] ->
- parse_number(Input@8, (Number * 10) + 6, Sign);
-
- [<<"7"/utf8>> | Input@9] ->
- parse_number(Input@9, (Number * 10) + 7, Sign);
-
- [<<"8"/utf8>> | Input@10] ->
- parse_number(Input@10, (Number * 10) + 8, Sign);
-
- [<<"9"/utf8>> | Input@11] ->
- parse_number(Input@11, (Number * 10) + 9, Sign);
-
- [<<"-"/utf8>> | Input@12] ->
- parse_date(Input@12, Number);
-
- [<<":"/utf8>> | Input@13] when Number < 24 ->
- parse_time_minute(Input@13, Number);
-
- [<<"."/utf8>> | Input@14] ->
- parse_float(Input@14, gleam@int:to_float(Number), Sign, 0.1);
-
- [<<"e"/utf8>>, <<"+"/utf8>> | Input@15] ->
- parse_exponent(
- Input@15,
- gleam@int:to_float(Number),
- Sign,
- 0,
- positive
- );
-
- [<<"e"/utf8>>, <<"-"/utf8>> | Input@16] ->
- parse_exponent(
- Input@16,
- gleam@int:to_float(Number),
- Sign,
- 0,
- negative
- );
-
- [<<"e"/utf8>> | Input@17] ->
- parse_exponent(
- Input@17,
- gleam@int:to_float(Number),
- Sign,
- 0,
- positive
- );
-
- [<<"E"/utf8>>, <<"+"/utf8>> | Input@18] ->
- parse_exponent(
- Input@18,
- gleam@int:to_float(Number),
- Sign,
- 0,
- positive
- );
-
- [<<"E"/utf8>>, <<"-"/utf8>> | Input@19] ->
- parse_exponent(
- Input@19,
- gleam@int:to_float(Number),
- Sign,
- 0,
- negative
- );
-
- [<<"E"/utf8>> | Input@20] ->
- parse_exponent(
- Input@20,
- gleam@int:to_float(Number),
- Sign,
- 0,
- positive
- );
-
- Input@21 ->
- Number@1 = case Sign of
- positive ->
- Number;
-
- negative ->
- - Number
- end,
- {ok, {{int, Number@1}, Input@21}}
- end.
-
--spec reverse_arrays_of_tables(toml()) -> toml().
-reverse_arrays_of_tables(Toml) ->
- case Toml of
- {array_of_tables, Tables} ->
- {array_of_tables, reverse_arrays_of_tables_array(Tables, [])};
-
- {table, Table} ->
- {table, reverse_arrays_of_tables_table(Table)};
-
- _ ->
- Toml
- end.
-
--spec reverse_arrays_of_tables_table(gleam@map:map_(binary(), toml())) -> gleam@map:map_(binary(), toml()).
-reverse_arrays_of_tables_table(Table) ->
- gleam@map:map_values(Table, fun(_, V) -> reverse_arrays_of_tables(V) end).
-
--spec reverse_arrays_of_tables_array(
- list(gleam@map:map_(binary(), toml())),
- list(gleam@map:map_(binary(), toml()))
-) -> list(gleam@map:map_(binary(), toml())).
-reverse_arrays_of_tables_array(Array, Acc) ->
- case Array of
- [] ->
- Acc;
-
- [First | Rest] ->
- First@1 = reverse_arrays_of_tables_table(First),
- reverse_arrays_of_tables_array(Rest, [First@1 | Acc])
- end.
-
--spec parse_inline_table_property(
- list(binary()),
- gleam@map:map_(binary(), toml())
-) -> {ok, {gleam@map:map_(binary(), toml()), list(binary())}} |
- {error, parse_error()}.
-parse_inline_table_property(Input, Properties) ->
- Input@1 = skip_whitespace(Input),
- do(
- parse_key(Input@1, []),
- fun(Key, Input@2) ->
- Input@3 = skip_line_whitespace(Input@2),
- expect(
- Input@3,
- <<"="/utf8>>,
- fun(Input@4) ->
- Input@5 = skip_line_whitespace(Input@4),
- do(
- parse_value(Input@5),
- fun(Value, Input@6) ->
- case insert(Properties, Key, Value) of
- {ok, Properties@1} ->
- {ok, {Properties@1, Input@6}};
-
- {error, E} ->
- {error, E}
- end
- end
- )
- end
- )
- end
- ).
-
--spec parse_value(list(binary())) -> {ok, {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_value(Input) ->
- case Input of
- [<<"t"/utf8>>, <<"r"/utf8>>, <<"u"/utf8>>, <<"e"/utf8>> | Input@1] ->
- {ok, {{bool, true}, Input@1}};
-
- [<<"f"/utf8>>,
- <<"a"/utf8>>,
- <<"l"/utf8>>,
- <<"s"/utf8>>,
- <<"e"/utf8>> |
- Input@2] ->
- {ok, {{bool, false}, Input@2}};
-
- [<<"n"/utf8>>, <<"a"/utf8>>, <<"n"/utf8>> | Input@3] ->
- {ok, {{nan, positive}, Input@3}};
-
- [<<"+"/utf8>>, <<"n"/utf8>>, <<"a"/utf8>>, <<"n"/utf8>> | Input@4] ->
- {ok, {{nan, positive}, Input@4}};
-
- [<<"-"/utf8>>, <<"n"/utf8>>, <<"a"/utf8>>, <<"n"/utf8>> | Input@5] ->
- {ok, {{nan, negative}, Input@5}};
-
- [<<"i"/utf8>>, <<"n"/utf8>>, <<"f"/utf8>> | Input@6] ->
- {ok, {{infinity, positive}, Input@6}};
-
- [<<"+"/utf8>>, <<"i"/utf8>>, <<"n"/utf8>>, <<"f"/utf8>> | Input@7] ->
- {ok, {{infinity, positive}, Input@7}};
-
- [<<"-"/utf8>>, <<"i"/utf8>>, <<"n"/utf8>>, <<"f"/utf8>> | Input@8] ->
- {ok, {{infinity, negative}, Input@8}};
-
- [<<"["/utf8>> | Input@9] ->
- parse_array(Input@9, []);
-
- [<<"{"/utf8>> | Input@10] ->
- parse_inline_table(Input@10, gleam@map:new());
-
- [<<"0"/utf8>>, <<"x"/utf8>> | Input@11] ->
- parse_hex(Input@11, 0, positive);
-
- [<<"+"/utf8>>, <<"0"/utf8>>, <<"x"/utf8>> | Input@12] ->
- parse_hex(Input@12, 0, positive);
-
- [<<"-"/utf8>>, <<"0"/utf8>>, <<"x"/utf8>> | Input@13] ->
- parse_hex(Input@13, 0, negative);
-
- [<<"0"/utf8>>, <<"o"/utf8>> | Input@14] ->
- parse_octal(Input@14, 0, positive);
-
- [<<"+"/utf8>>, <<"0"/utf8>>, <<"o"/utf8>> | Input@15] ->
- parse_octal(Input@15, 0, positive);
-
- [<<"-"/utf8>>, <<"0"/utf8>>, <<"o"/utf8>> | Input@16] ->
- parse_octal(Input@16, 0, negative);
-
- [<<"0"/utf8>>, <<"b"/utf8>> | Input@17] ->
- parse_binary(Input@17, 0, positive);
-
- [<<"+"/utf8>>, <<"0"/utf8>>, <<"b"/utf8>> | Input@18] ->
- parse_binary(Input@18, 0, positive);
-
- [<<"-"/utf8>>, <<"0"/utf8>>, <<"b"/utf8>> | Input@19] ->
- parse_binary(Input@19, 0, negative);
-
- [<<"+"/utf8>> | Input@20] ->
- parse_number(Input@20, 0, positive);
-
- [<<"-"/utf8>> | Input@21] ->
- parse_number(Input@21, 0, negative);
-
- [<<"0"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"1"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"2"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"3"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"4"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"5"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"6"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"7"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"8"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"9"/utf8>> | _] ->
- parse_number(Input, 0, positive);
-
- [<<"\""/utf8>>, <<"\""/utf8>>, <<"\""/utf8>> | Input@22] ->
- parse_multi_line_string(Input@22, <<""/utf8>>);
-
- [<<"\""/utf8>> | Input@23] ->
- parse_string(Input@23, <<""/utf8>>);
-
- [<<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>> | Input@24] ->
- parse_multi_line_literal_string(Input@24, <<""/utf8>>);
-
- [<<"'"/utf8>> | Input@25] ->
- parse_literal_string(Input@25, <<""/utf8>>);
-
- [G | _] ->
- {error, {unexpected, G, <<"value"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"value"/utf8>>}}
- end.
-
--spec parse_inline_table(list(binary()), gleam@map:map_(binary(), toml())) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_inline_table(Input, Properties) ->
- Input@1 = skip_whitespace(Input),
- case Input@1 of
- [<<"}"/utf8>> | Input@2] ->
- {ok, {{inline_table, Properties}, Input@2}};
-
- _ ->
- case parse_inline_table_property(Input@1, Properties) of
- {ok, {Properties@1, Input@3}} ->
- Input@4 = skip_whitespace(Input@3),
- case Input@4 of
- [<<"}"/utf8>> | Input@5] ->
- {ok, {{inline_table, Properties@1}, Input@5}};
-
- [<<","/utf8>> | Input@6] ->
- Input@7 = skip_whitespace(Input@6),
- parse_inline_table(Input@7, Properties@1);
-
- [G | _] ->
- {error, {unexpected, G, <<"}"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"}"/utf8>>}}
- end;
-
- {error, E} ->
- {error, E}
- end
- end.
-
--spec parse_key_value(list(binary()), gleam@map:map_(binary(), toml())) -> {ok,
- {gleam@map:map_(binary(), toml()), list(binary())}} |
- {error, parse_error()}.
-parse_key_value(Input, Toml) ->
- do(
- parse_key(Input, []),
- fun(Key, Input@1) ->
- Input@2 = skip_line_whitespace(Input@1),
- expect(
- Input@2,
- <<"="/utf8>>,
- fun(Input@3) ->
- Input@4 = skip_line_whitespace(Input@3),
- do(
- parse_value(Input@4),
- fun(Value, Input@5) -> case insert(Toml, Key, Value) of
- {ok, Toml@1} ->
- {ok, {Toml@1, Input@5}};
-
- {error, E} ->
- {error, E}
- end end
- )
- end
- )
- end
- ).
-
--spec parse_table(list(binary()), gleam@map:map_(binary(), toml())) -> {ok,
- {gleam@map:map_(binary(), toml()), list(binary())}} |
- {error, parse_error()}.
-parse_table(Input, Toml) ->
- Input@1 = skip_whitespace(Input),
- case Input@1 of
- [<<"["/utf8>> | _] ->
- {ok, {Toml, Input@1}};
-
- [] ->
- {ok, {Toml, Input@1}};
-
- _ ->
- case parse_key_value(Input@1, Toml) of
- {ok, {Toml@1, Input@2}} ->
- case skip_line_whitespace(Input@2) of
- [] ->
- {ok, {Toml@1, []}};
-
- [<<"\n"/utf8>> | In] ->
- parse_table(In, Toml@1);
-
- [<<"\r\n"/utf8>> | In] ->
- parse_table(In, Toml@1);
-
- [G | _] ->
- {error, {unexpected, G, <<"\n"/utf8>>}}
- end;
-
- E ->
- E
- end
- end.
-
--spec parse_array_of_tables(list(binary())) -> {ok,
- {{list(binary()), gleam@map:map_(binary(), toml())}, list(binary())}} |
- {error, parse_error()}.
-parse_array_of_tables(Input) ->
- Input@1 = skip_line_whitespace(Input),
- do(
- parse_key(Input@1, []),
- fun(Key, Input@2) ->
- expect(
- Input@2,
- <<"]"/utf8>>,
- fun(Input@3) ->
- expect(
- Input@3,
- <<"]"/utf8>>,
- fun(Input@4) ->
- do(
- parse_table(Input@4, gleam@map:new()),
- fun(Table, Input@5) ->
- {ok, {{Key, Table}, Input@5}}
- end
- )
- end
- )
- end
- )
- end
- ).
-
--spec parse_table_and_header(list(binary())) -> {ok,
- {{list(binary()), gleam@map:map_(binary(), toml())}, list(binary())}} |
- {error, parse_error()}.
-parse_table_and_header(Input) ->
- do(
- parse_table_header(Input),
- fun(Key, Input@1) ->
- do(
- parse_table(Input@1, gleam@map:new()),
- fun(Table, Input@2) -> {ok, {{Key, Table}, Input@2}} end
- )
- end
- ).
-
--spec parse_tables(list(binary()), gleam@map:map_(binary(), toml())) -> {ok,
- gleam@map:map_(binary(), toml())} |
- {error, parse_error()}.
-parse_tables(Input, Toml) ->
- case Input of
- [<<"["/utf8>>, <<"["/utf8>> | Input@1] ->
- case parse_array_of_tables(Input@1) of
- {error, E} ->
- {error, E};
-
- {ok, {{Key, Table}, Input@2}} ->
- case insert(Toml, Key, {array_of_tables, [Table]}) of
- {ok, Toml@1} ->
- parse_tables(Input@2, Toml@1);
-
- {error, E@1} ->
- {error, E@1}
- end
- end;
-
- [<<"["/utf8>> | Input@3] ->
- case parse_table_and_header(Input@3) of
- {error, E@2} ->
- {error, E@2};
-
- {ok, {{Key@1, Table@1}, Input@4}} ->
- case insert(Toml, Key@1, {table, Table@1}) of
- {ok, Toml@2} ->
- parse_tables(Input@4, Toml@2);
-
- {error, E@3} ->
- {error, E@3}
- end
- end;
-
- [G | _] ->
- {error, {unexpected, G, <<"["/utf8>>}};
-
- [] ->
- {ok, Toml}
- end.
-
--spec parse(binary()) -> {ok, gleam@map:map_(binary(), toml())} |
- {error, parse_error()}.
-parse(Input) ->
- Input@1 = gleam@string:to_graphemes(Input),
- Input@2 = drop_comments(Input@1, []),
- Input@3 = skip_whitespace(Input@2),
- do(
- parse_table(Input@3, gleam@map:new()),
- fun(Toml, Input@4) -> case parse_tables(Input@4, Toml) of
- {ok, Toml@1} ->
- {ok, reverse_arrays_of_tables_table(Toml@1)};
-
- {error, E} ->
- {error, E}
- end end
- ).
-
--spec parse_array(list(binary()), list(toml())) -> {ok,
- {toml(), list(binary())}} |
- {error, parse_error()}.
-parse_array(Input, Elements) ->
- Input@1 = skip_whitespace(Input),
- case Input@1 of
- [<<"]"/utf8>> | Input@2] ->
- {ok, {{array, gleam@list:reverse(Elements)}, Input@2}};
-
- _ ->
- do(
- parse_value(Input@1),
- fun(Element, Input@3) ->
- Elements@1 = [Element | Elements],
- Input@4 = skip_whitespace(Input@3),
- case Input@4 of
- [<<"]"/utf8>> | Input@5] ->
- {ok,
- {{array, gleam@list:reverse(Elements@1)},
- Input@5}};
-
- [<<","/utf8>> | Input@6] ->
- Input@7 = skip_whitespace(Input@6),
- parse_array(Input@7, Elements@1);
-
- [G | _] ->
- {error, {unexpected, G, <<"]"/utf8>>}};
-
- [] ->
- {error, {unexpected, <<"EOF"/utf8>>, <<"]"/utf8>>}}
- end
- end
- )
- end.
diff --git a/aoc2023/build/packages/tom/src/tom.gleam b/aoc2023/build/packages/tom/src/tom.gleam
deleted file mode 100644
index e19ce3e..0000000
--- a/aoc2023/build/packages/tom/src/tom.gleam
+++ /dev/null
@@ -1,1317 +0,0 @@
-//// A pure Gleam TOML parser!
-////
-//// ```gleam
-//// import tom
-////
-//// const config = "
-//// [person]
-//// name = \"Lucy\"
-//// is_cool = true
-//// "
-////
-//// pub fn main() {
-//// // Parse a string of TOML
-//// let assert Ok(parsed) = tom.parse(config)
-////
-//// // Now you can work with the data directly, or you can use the `get_*`
-//// // functions to retrieve values.
-////
-//// tom.get_string(parsed, ["person", "name"])
-//// // -> Ok("Lucy")
-////
-//// let is_cool = tom.get_bool(parsed, ["person", "is_cool"])
-//// // -> Ok(True)
-//// }
-//// ```
-
-import gleam/int
-import gleam/list
-import gleam/float
-import gleam/string
-import gleam/result
-import gleam/map.{type Map}
-
-/// A TOML document.
-pub type Toml {
- Int(Int)
- Float(Float)
- /// Infinity is a valid number in TOML but Gleam does not support it, so this
- /// variant represents the infinity values.
- Infinity(Sign)
- /// NaN is a valid number in TOML but Gleam does not support it, so this
- /// variant represents the NaN values.
- Nan(Sign)
- Bool(Bool)
- String(String)
- Date(Date)
- Time(Time)
- DateTime(DateTime)
- Array(List(Toml))
- ArrayOfTables(List(Map(String, Toml)))
- Table(Map(String, Toml))
- InlineTable(Map(String, Toml))
-}
-
-pub type DateTime {
- DateTimeValue(date: Date, time: Time, offset: Offset)
-}
-
-pub type Date {
- DateValue(year: Int, month: Int, day: Int)
-}
-
-pub type Time {
- TimeValue(hour: Int, minute: Int, second: Int, millisecond: Int)
-}
-
-pub type Offset {
- Local
- Offset(direction: Sign, hours: Int, minutes: Int)
-}
-
-pub type Sign {
- Positive
- Negative
-}
-
-/// An error that can occur when parsing a TOML document.
-pub type ParseError {
- /// An unexpected character was encountered when parsing the document.
- Unexpected(got: String, expected: String)
- /// More than one items have the same key in the document.
- KeyAlreadyInUse(key: List(String))
-}
-
-type Tokens =
- List(String)
-
-type Parsed(a) =
- Result(#(a, Tokens), ParseError)
-
-/// A number of any kind, returned by the `get_number` function.
-pub type Number {
- NumberInt(Int)
- NumberFloat(Float)
- NumberInfinity(Sign)
- NumberNan(Sign)
-}
-
-/// An error that can occur when retrieving a value from a TOML document with
-/// one of the `get_*` functions.
-pub type GetError {
- /// There was no value at the given key.
- NotFound(key: List(String))
- /// The value at the given key was not of the expected type.
- WrongType(key: List(String), expected: String, got: String)
-}
-
-// TODO: test
-/// Get a value of any type from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = 1")
-/// get(parsed, ["a", "b", "c"])
-/// // -> Ok(Int(1))
-/// ```
-///
-pub fn get(toml: Map(String, Toml), key: List(String)) -> Result(Toml, GetError) {
- case key {
- [] -> Error(NotFound([]))
- [k] -> result.replace_error(map.get(toml, k), NotFound([k]))
- [k, ..key] -> {
- case map.get(toml, k) {
- Ok(Table(t)) -> push_key(get(t, key), k)
- Ok(other) -> Error(WrongType([k], "Table", classify(other)))
- Error(_) -> Error(NotFound([k]))
- }
- }
- }
-}
-
-// TODO: test
-/// Get an int from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = 1")
-/// get_int(parsed, ["a", "b", "c"])
-/// // -> Ok(1)
-/// ```
-///
-pub fn get_int(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Int, GetError) {
- case get(toml, key) {
- Ok(Int(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "Int", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a float from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = 1.1")
-/// get_float(parsed, ["a", "b", "c"])
-/// // -> Ok(1.1)
-/// ```
-///
-pub fn get_float(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Float, GetError) {
- case get(toml, key) {
- Ok(Float(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "Float", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a bool from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = true")
-/// get_bool(parsed, ["a", "b", "c"])
-/// // -> Ok(True)
-/// ```
-///
-pub fn get_bool(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Bool, GetError) {
- case get(toml, key) {
- Ok(Bool(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "Bool", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a string from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = \"ok\"")
-/// get_string(parsed, ["a", "b", "c"])
-/// // -> Ok("ok")
-/// ```
-///
-pub fn get_string(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(String, GetError) {
- case get(toml, key) {
- Ok(String(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "String", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a date from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = 1979-05-27")
-/// get_date(parsed, ["a", "b", "c"])
-/// // -> Ok("1979-05-27")
-/// ```
-///
-pub fn get_date(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Date, GetError) {
- case get(toml, key) {
- Ok(Date(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "Date", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a time from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = 07:32:00")
-/// get_time(parsed, ["a", "b", "c"])
-/// // -> Ok("07:32:00")
-/// ```
-///
-pub fn get_time(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Time, GetError) {
- case get(toml, key) {
- Ok(Time(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "Time", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a date-time from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = 1979-05-27T07:32:00")
-/// get_date_time(parsed, ["a", "b", "c"])
-/// // -> Ok("1979-05-27T07:32:00")
-/// ```
-///
-pub fn get_date_time(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(DateTime, GetError) {
- case get(toml, key) {
- Ok(DateTime(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "DateTime", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get an array from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = [1, 2]")
-/// get_array(parsed, ["a", "b", "c"])
-/// // -> Ok([Int(1), Int(2)])
-/// ```
-///
-pub fn get_array(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(List(Toml), GetError) {
- case get(toml, key) {
- Ok(Array(i)) -> Ok(i)
- Ok(ArrayOfTables(i)) -> Ok(list.map(i, Table))
- Ok(other) -> Error(WrongType(key, "Array", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a table from a TOML document.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = { d = 1 }")
-/// get_table(parsed, ["a", "b", "c"])
-/// // -> Ok(map.from_list([#("d", Int(1))]))
-/// ```
-///
-pub fn get_table(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Map(String, Toml), GetError) {
- case get(toml, key) {
- Ok(Table(i)) -> Ok(i)
- Ok(InlineTable(i)) -> Ok(i)
- Ok(other) -> Error(WrongType(key, "Table", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-// TODO: test
-/// Get a number of any kind from a TOML document.
-/// This could be an int, a float, a NaN, or an infinity.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let assert Ok(parsed) = parse("a.b.c = { d = inf }")
-/// get_number(parsed, ["a", "b", "c"])
-/// // -> Ok(NumberInfinity(Positive)))
-/// ```
-///
-pub fn get_number(
- toml: Map(String, Toml),
- key: List(String),
-) -> Result(Number, GetError) {
- case get(toml, key) {
- Ok(Int(x)) -> Ok(NumberInt(x))
- Ok(Float(x)) -> Ok(NumberFloat(x))
- Ok(Nan(x)) -> Ok(NumberNan(x))
- Ok(Infinity(x)) -> Ok(NumberInfinity(x))
- Ok(other) -> Error(WrongType(key, "Number", classify(other)))
- Error(e) -> Error(e)
- }
-}
-
-fn classify(toml: Toml) -> String {
- case toml {
- Int(_) -> "Int"
- Float(_) -> "Float"
- Nan(Positive) -> "NaN"
- Nan(Negative) -> "Negative NaN"
- Infinity(Positive) -> "Infinity"
- Infinity(Negative) -> "Negative Infinity"
- Bool(_) -> "Bool"
- String(_) -> "String"
- Date(_) -> "Date"
- Time(_) -> "Time"
- DateTime(_) -> "DateTime"
- Array(_) -> "Array"
- ArrayOfTables(_) -> "Array"
- Table(_) -> "Table"
- InlineTable(_) -> "Table"
- }
-}
-
-fn push_key(result: Result(t, GetError), key: String) -> Result(t, GetError) {
- case result {
- Ok(t) -> Ok(t)
- Error(NotFound(path)) -> Error(NotFound([key, ..path]))
- Error(WrongType(path, expected, got)) ->
- Error(WrongType([key, ..path], expected, got))
- }
-}
-
-pub fn parse(input: String) -> Result(Map(String, Toml), ParseError) {
- let input = string.to_graphemes(input)
- let input = drop_comments(input, [])
- let input = skip_whitespace(input)
- use toml, input <- do(parse_table(input, map.new()))
- case parse_tables(input, toml) {
- Ok(toml) -> Ok(reverse_arrays_of_tables_table(toml))
- Error(e) -> Error(e)
- }
-}
-
-fn parse_tables(
- input: Tokens,
- toml: Map(String, Toml),
-) -> Result(Map(String, Toml), ParseError) {
- case input {
- ["[", "[", ..input] -> {
- case parse_array_of_tables(input) {
- Error(e) -> Error(e)
- Ok(#(#(key, table), input)) -> {
- case insert(toml, key, ArrayOfTables([table])) {
- Ok(toml) -> parse_tables(input, toml)
- Error(e) -> Error(e)
- }
- }
- }
- }
- ["[", ..input] -> {
- case parse_table_and_header(input) {
- Error(e) -> Error(e)
- Ok(#(#(key, table), input)) -> {
- case insert(toml, key, Table(table)) {
- Ok(toml) -> parse_tables(input, toml)
- Error(e) -> Error(e)
- }
- }
- }
- }
- [g, ..] -> Error(Unexpected(g, "["))
- [] -> Ok(toml)
- }
-}
-
-fn parse_array_of_tables(
- input: Tokens,
-) -> Parsed(#(List(String), Map(String, Toml))) {
- let input = skip_line_whitespace(input)
- use key, input <- do(parse_key(input, []))
- use input <- expect(input, "]")
- use input <- expect(input, "]")
- use table, input <- do(parse_table(input, map.new()))
- Ok(#(#(key, table), input))
-}
-
-fn parse_table_header(input: Tokens) -> Parsed(List(String)) {
- let input = skip_line_whitespace(input)
- use key, input <- do(parse_key(input, []))
- use input <- expect(input, "]")
- let input = skip_line_whitespace(input)
- use input <- expect_end_of_line(input)
- Ok(#(key, input))
-}
-
-fn parse_table_and_header(
- input: Tokens,
-) -> Parsed(#(List(String), Map(String, Toml))) {
- use key, input <- do(parse_table_header(input))
- use table, input <- do(parse_table(input, map.new()))
- Ok(#(#(key, table), input))
-}
-
-fn parse_table(
- input: Tokens,
- toml: Map(String, Toml),
-) -> Parsed(Map(String, Toml)) {
- let input = skip_whitespace(input)
- case input {
- ["[", ..] | [] -> Ok(#(toml, input))
- _ ->
- case parse_key_value(input, toml) {
- Ok(#(toml, input)) ->
- case skip_line_whitespace(input) {
- [] -> Ok(#(toml, []))
- ["\n", ..in] | ["\r\n", ..in] -> parse_table(in, toml)
- [g, ..] -> Error(Unexpected(g, "\n"))
- }
- e -> e
- }
- }
-}
-
-fn parse_key_value(
- input: Tokens,
- toml: Map(String, Toml),
-) -> Parsed(Map(String, Toml)) {
- use key, input <- do(parse_key(input, []))
- let input = skip_line_whitespace(input)
- use input <- expect(input, "=")
- let input = skip_line_whitespace(input)
- use value, input <- do(parse_value(input))
- case insert(toml, key, value) {
- Ok(toml) -> Ok(#(toml, input))
- Error(e) -> Error(e)
- }
-}
-
-fn insert(
- table: Map(String, Toml),
- key: List(String),
- value: Toml,
-) -> Result(Map(String, Toml), ParseError) {
- case insert_loop(table, key, value) {
- Ok(table) -> Ok(table)
- Error(path) -> Error(KeyAlreadyInUse(path))
- }
-}
-
-fn insert_loop(
- table: Map(String, Toml),
- key: List(String),
- value: Toml,
-) -> Result(Map(String, Toml), List(String)) {
- case key {
- [] -> panic as "unreachable"
- [k] -> {
- case map.get(table, k) {
- Error(Nil) -> Ok(map.insert(table, k, value))
- Ok(old) -> merge(table, k, old, value)
- }
- }
- [k, ..key] -> {
- case map.get(table, k) {
- Error(Nil) -> {
- case insert_loop(map.new(), key, value) {
- Ok(inner) -> Ok(map.insert(table, k, Table(inner)))
- Error(path) -> Error([k, ..path])
- }
- }
- Ok(ArrayOfTables([inner, ..rest])) -> {
- case insert_loop(inner, key, value) {
- Ok(inner) ->
- Ok(map.insert(table, k, ArrayOfTables([inner, ..rest])))
- Error(path) -> Error([k, ..path])
- }
- }
- Ok(Table(inner)) -> {
- case insert_loop(inner, key, value) {
- Ok(inner) -> Ok(map.insert(table, k, Table(inner)))
- Error(path) -> Error([k, ..path])
- }
- }
- Ok(_) -> Error([k])
- }
- }
- }
-}
-
-fn merge(
- table: Map(String, Toml),
- key: String,
- old: Toml,
- new: Toml,
-) -> Result(Map(String, Toml), List(String)) {
- case old, new {
- // When both are arrays of tables then they are merged together
- ArrayOfTables(tables), ArrayOfTables(new) ->
- Ok(map.insert(table, key, ArrayOfTables(list.append(new, tables))))
-
- _, _ -> Error([key])
- }
-}
-
-fn expect_end_of_line(input: Tokens, next: fn(Tokens) -> Parsed(a)) -> Parsed(a) {
- case input {
- ["\n", ..input] -> next(input)
- ["\r\n", ..input] -> next(input)
- [g, ..] -> Error(Unexpected(g, "\n"))
- [] -> Error(Unexpected("EOF", "\n"))
- }
-}
-
-fn parse_value(input) -> Parsed(Toml) {
- case input {
- ["t", "r", "u", "e", ..input] -> Ok(#(Bool(True), input))
- ["f", "a", "l", "s", "e", ..input] -> Ok(#(Bool(False), input))
-
- ["n", "a", "n", ..input] -> Ok(#(Nan(Positive), input))
- ["+", "n", "a", "n", ..input] -> Ok(#(Nan(Positive), input))
- ["-", "n", "a", "n", ..input] -> Ok(#(Nan(Negative), input))
-
- ["i", "n", "f", ..input] -> Ok(#(Infinity(Positive), input))
- ["+", "i", "n", "f", ..input] -> Ok(#(Infinity(Positive), input))
- ["-", "i", "n", "f", ..input] -> Ok(#(Infinity(Negative), input))
-
- ["[", ..input] -> parse_array(input, [])
- ["{", ..input] -> parse_inline_table(input, map.new())
-
- ["0", "x", ..input] -> parse_hex(input, 0, Positive)
- ["+", "0", "x", ..input] -> parse_hex(input, 0, Positive)
- ["-", "0", "x", ..input] -> parse_hex(input, 0, Negative)
-
- ["0", "o", ..input] -> parse_octal(input, 0, Positive)
- ["+", "0", "o", ..input] -> parse_octal(input, 0, Positive)
- ["-", "0", "o", ..input] -> parse_octal(input, 0, Negative)
-
- ["0", "b", ..input] -> parse_binary(input, 0, Positive)
- ["+", "0", "b", ..input] -> parse_binary(input, 0, Positive)
- ["-", "0", "b", ..input] -> parse_binary(input, 0, Negative)
-
- ["+", ..input] -> parse_number(input, 0, Positive)
- ["-", ..input] -> parse_number(input, 0, Negative)
- ["0", ..]
- | ["1", ..]
- | ["2", ..]
- | ["3", ..]
- | ["4", ..]
- | ["5", ..]
- | ["6", ..]
- | ["7", ..]
- | ["8", ..]
- | ["9", ..] -> parse_number(input, 0, Positive)
-
- ["\"", "\"", "\"", ..input] -> parse_multi_line_string(input, "")
- ["\"", ..input] -> parse_string(input, "")
-
- ["'", "'", "'", ..input] -> parse_multi_line_literal_string(input, "")
- ["'", ..input] -> parse_literal_string(input, "")
-
- [g, ..] -> Error(Unexpected(g, "value"))
- [] -> Error(Unexpected("EOF", "value"))
- }
-}
-
-fn parse_key(input: Tokens, segments: List(String)) -> Parsed(List(String)) {
- use segment, input <- do(parse_key_segment(input))
- let segments = [segment, ..segments]
- let input = skip_line_whitespace(input)
-
- case input {
- [".", ..input] -> parse_key(input, segments)
- _ -> Ok(#(list.reverse(segments), input))
- }
-}
-
-fn parse_key_segment(input: Tokens) -> Parsed(String) {
- let input = skip_line_whitespace(input)
- case input {
- ["=", ..] -> Error(Unexpected("=", "Key"))
- ["\n", ..] -> Error(Unexpected("\n", "Key"))
- ["\r\n", ..] -> Error(Unexpected("\r\n", "Key"))
- ["[", ..] -> Error(Unexpected("[", "Key"))
- ["\"", ..input] -> parse_key_quoted(input, "\"", "")
- ["'", ..input] -> parse_key_quoted(input, "'", "")
- _ -> parse_key_bare(input, "")
- }
-}
-
-fn parse_key_quoted(
- input: Tokens,
- close: String,
- name: String,
-) -> Parsed(String) {
- case input {
- [g, ..input] if g == close -> Ok(#(name, input))
- [g, ..input] -> parse_key_quoted(input, close, name <> g)
- [] -> Error(Unexpected("EOF", close))
- }
-}
-
-fn parse_key_bare(input: Tokens, name: String) -> Parsed(String) {
- case input {
- [" ", ..input] if name != "" -> Ok(#(name, input))
- ["=", ..] if name != "" -> Ok(#(name, input))
- [".", ..] if name != "" -> Ok(#(name, input))
- ["]", ..] if name != "" -> Ok(#(name, input))
- [",", ..] if name != "" -> Error(Unexpected(",", "="))
- ["\n", ..] if name != "" -> Error(Unexpected("\n", "="))
- ["\r\n", ..] if name != "" -> Error(Unexpected("\r\n", "="))
- ["\n", ..] -> Error(Unexpected("\n", "key"))
- ["\r\n", ..] -> Error(Unexpected("\r\n", "key"))
- ["]", ..] -> Error(Unexpected("]", "key"))
- [",", ..] -> Error(Unexpected(",", "key"))
- [g, ..input] -> parse_key_bare(input, name <> g)
- [] -> Error(Unexpected("EOF", "key"))
- }
-}
-
-fn skip_line_whitespace(input: Tokens) -> Tokens {
- list.drop_while(input, fn(g) { g == " " || g == "\t" })
-}
-
-fn skip_whitespace(input: Tokens) -> Tokens {
- case input {
- [" ", ..input] -> skip_whitespace(input)
- ["\t", ..input] -> skip_whitespace(input)
- ["\n", ..input] -> skip_whitespace(input)
- ["\r\n", ..input] -> skip_whitespace(input)
- input -> input
- }
-}
-
-fn drop_comments(input: Tokens, acc: Tokens) -> Tokens {
- case input {
- ["#", ..input] ->
- input
- |> list.drop_while(fn(g) { g != "\n" })
- |> drop_comments(acc)
- [g, ..input] -> drop_comments(input, [g, ..acc])
- [] -> list.reverse(acc)
- }
-}
-
-fn do(
- result: Result(#(a, Tokens), ParseError),
- next: fn(a, Tokens) -> Result(b, ParseError),
-) -> Result(b, ParseError) {
- case result {
- Ok(#(a, input)) -> next(a, input)
- Error(e) -> Error(e)
- }
-}
-
-fn expect(
- input: Tokens,
- expected: String,
- next: fn(Tokens) -> Parsed(a),
-) -> Parsed(a) {
- case input {
- [g, ..input] if g == expected -> next(input)
- [g, ..] -> Error(Unexpected(g, expected))
- [] -> Error(Unexpected("EOF", expected))
- }
-}
-
-fn parse_inline_table(
- input: Tokens,
- properties: Map(String, Toml),
-) -> Parsed(Toml) {
- let input = skip_whitespace(input)
- case input {
- ["}", ..input] -> Ok(#(InlineTable(properties), input))
- _ ->
- case parse_inline_table_property(input, properties) {
- Ok(#(properties, input)) -> {
- let input = skip_whitespace(input)
- case input {
- ["}", ..input] -> Ok(#(InlineTable(properties), input))
- [",", ..input] -> {
- let input = skip_whitespace(input)
- parse_inline_table(input, properties)
- }
- [g, ..] -> Error(Unexpected(g, "}"))
- [] -> Error(Unexpected("EOF", "}"))
- }
- }
- Error(e) -> Error(e)
- }
- }
-}
-
-fn parse_inline_table_property(
- input: Tokens,
- properties: Map(String, Toml),
-) -> Parsed(Map(String, Toml)) {
- let input = skip_whitespace(input)
- use key, input <- do(parse_key(input, []))
- let input = skip_line_whitespace(input)
- use input <- expect(input, "=")
- let input = skip_line_whitespace(input)
- use value, input <- do(parse_value(input))
- case insert(properties, key, value) {
- Ok(properties) -> Ok(#(properties, input))
- Error(e) -> Error(e)
- }
-}
-
-fn parse_array(input: Tokens, elements: List(Toml)) -> Parsed(Toml) {
- let input = skip_whitespace(input)
- case input {
- ["]", ..input] -> Ok(#(Array(list.reverse(elements)), input))
- _ -> {
- use element, input <- do(parse_value(input))
- let elements = [element, ..elements]
- let input = skip_whitespace(input)
- case input {
- ["]", ..input] -> Ok(#(Array(list.reverse(elements)), input))
- [",", ..input] -> {
- let input = skip_whitespace(input)
- parse_array(input, elements)
- }
- [g, ..] -> Error(Unexpected(g, "]"))
- [] -> Error(Unexpected("EOF", "]"))
- }
- }
- }
-}
-
-fn parse_hex(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) {
- case input {
- ["_", ..input] -> parse_hex(input, number, sign)
- ["0", ..input] -> parse_hex(input, number * 16 + 0, sign)
- ["1", ..input] -> parse_hex(input, number * 16 + 1, sign)
- ["2", ..input] -> parse_hex(input, number * 16 + 2, sign)
- ["3", ..input] -> parse_hex(input, number * 16 + 3, sign)
- ["4", ..input] -> parse_hex(input, number * 16 + 4, sign)
- ["5", ..input] -> parse_hex(input, number * 16 + 5, sign)
- ["6", ..input] -> parse_hex(input, number * 16 + 6, sign)
- ["7", ..input] -> parse_hex(input, number * 16 + 7, sign)
- ["8", ..input] -> parse_hex(input, number * 16 + 8, sign)
- ["9", ..input] -> parse_hex(input, number * 16 + 9, sign)
- ["a", ..input] -> parse_hex(input, number * 16 + 10, sign)
- ["b", ..input] -> parse_hex(input, number * 16 + 11, sign)
- ["c", ..input] -> parse_hex(input, number * 16 + 12, sign)
- ["d", ..input] -> parse_hex(input, number * 16 + 13, sign)
- ["e", ..input] -> parse_hex(input, number * 16 + 14, sign)
- ["f", ..input] -> parse_hex(input, number * 16 + 15, sign)
- ["A", ..input] -> parse_hex(input, number * 16 + 10, sign)
- ["B", ..input] -> parse_hex(input, number * 16 + 11, sign)
- ["C", ..input] -> parse_hex(input, number * 16 + 12, sign)
- ["D", ..input] -> parse_hex(input, number * 16 + 13, sign)
- ["E", ..input] -> parse_hex(input, number * 16 + 14, sign)
- ["F", ..input] -> parse_hex(input, number * 16 + 15, sign)
-
- // Anything else and the number is terminated
- input -> {
- let number = case sign {
- Positive -> number
- Negative -> -number
- }
- Ok(#(Int(number), input))
- }
- }
-}
-
-fn parse_octal(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) {
- case input {
- ["_", ..input] -> parse_octal(input, number, sign)
- ["0", ..input] -> parse_octal(input, number * 8 + 0, sign)
- ["1", ..input] -> parse_octal(input, number * 8 + 1, sign)
- ["2", ..input] -> parse_octal(input, number * 8 + 2, sign)
- ["3", ..input] -> parse_octal(input, number * 8 + 3, sign)
- ["4", ..input] -> parse_octal(input, number * 8 + 4, sign)
- ["5", ..input] -> parse_octal(input, number * 8 + 5, sign)
- ["6", ..input] -> parse_octal(input, number * 8 + 6, sign)
- ["7", ..input] -> parse_octal(input, number * 8 + 7, sign)
-
- // Anything else and the number is terminated
- input -> {
- let number = case sign {
- Positive -> number
- Negative -> -number
- }
- Ok(#(Int(number), input))
- }
- }
-}
-
-fn parse_binary(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) {
- case input {
- ["_", ..input] -> parse_binary(input, number, sign)
- ["0", ..input] -> parse_binary(input, number * 2 + 0, sign)
- ["1", ..input] -> parse_binary(input, number * 2 + 1, sign)
-
- // Anything else and the number is terminated
- input -> {
- let number = case sign {
- Positive -> number
- Negative -> -number
- }
- Ok(#(Int(number), input))
- }
- }
-}
-
-fn parse_number(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) {
- case input {
- ["_", ..input] -> parse_number(input, number, sign)
- ["0", ..input] -> parse_number(input, number * 10 + 0, sign)
- ["1", ..input] -> parse_number(input, number * 10 + 1, sign)
- ["2", ..input] -> parse_number(input, number * 10 + 2, sign)
- ["3", ..input] -> parse_number(input, number * 10 + 3, sign)
- ["4", ..input] -> parse_number(input, number * 10 + 4, sign)
- ["5", ..input] -> parse_number(input, number * 10 + 5, sign)
- ["6", ..input] -> parse_number(input, number * 10 + 6, sign)
- ["7", ..input] -> parse_number(input, number * 10 + 7, sign)
- ["8", ..input] -> parse_number(input, number * 10 + 8, sign)
- ["9", ..input] -> parse_number(input, number * 10 + 9, sign)
-
- ["-", ..input] -> parse_date(input, number)
- [":", ..input] if number < 24 -> parse_time_minute(input, number)
-
- [".", ..input] -> parse_float(input, int.to_float(number), sign, 0.1)
-
- ["e", "+", ..input] ->
- parse_exponent(input, int.to_float(number), sign, 0, Positive)
- ["e", "-", ..input] ->
- parse_exponent(input, int.to_float(number), sign, 0, Negative)
- ["e", ..input] ->
- parse_exponent(input, int.to_float(number), sign, 0, Positive)
- ["E", "+", ..input] ->
- parse_exponent(input, int.to_float(number), sign, 0, Positive)
- ["E", "-", ..input] ->
- parse_exponent(input, int.to_float(number), sign, 0, Negative)
- ["E", ..input] ->
- parse_exponent(input, int.to_float(number), sign, 0, Positive)
-
- // Anything else and the number is terminated
- input -> {
- let number = case sign {
- Positive -> number
- Negative -> -number
- }
- Ok(#(Int(number), input))
- }
- }
-}
-
-fn parse_exponent(
- input: Tokens,
- n: Float,
- n_sign: Sign,
- ex: Int,
- ex_sign: Sign,
-) -> Parsed(Toml) {
- case input {
- ["_", ..input] -> parse_exponent(input, n, n_sign, ex, ex_sign)
- ["0", ..input] -> parse_exponent(input, n, n_sign, ex * 10, ex_sign)
- ["1", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 1, ex_sign)
- ["2", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 2, ex_sign)
- ["3", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 3, ex_sign)
- ["4", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 4, ex_sign)
- ["5", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 5, ex_sign)
- ["6", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 6, ex_sign)
- ["7", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 7, ex_sign)
- ["8", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 8, ex_sign)
- ["9", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 9, ex_sign)
-
- // Anything else and the number is terminated
- input -> {
- let number = case n_sign {
- Positive -> n
- Negative -> n *. -1.0
- }
- let exponent =
- int.to_float(case ex_sign {
- Positive -> ex
- Negative -> -ex
- })
- let multiplier = case float.power(10.0, exponent) {
- Ok(multiplier) -> multiplier
- Error(_) -> 1.0
- }
- Ok(#(Float(number *. multiplier), input))
- }
- }
-}
-
-fn parse_float(
- input: Tokens,
- number: Float,
- sign: Sign,
- unit: Float,
-) -> Parsed(Toml) {
- case input {
- ["_", ..input] -> parse_float(input, number, sign, unit)
- ["0", ..input] -> parse_float(input, number, sign, unit *. 0.1)
- ["1", ..input] ->
- parse_float(input, number +. 1.0 *. unit, sign, unit *. 0.1)
- ["2", ..input] ->
- parse_float(input, number +. 2.0 *. unit, sign, unit *. 0.1)
- ["3", ..input] ->
- parse_float(input, number +. 3.0 *. unit, sign, unit *. 0.1)
- ["4", ..input] ->
- parse_float(input, number +. 4.0 *. unit, sign, unit *. 0.1)
- ["5", ..input] ->
- parse_float(input, number +. 5.0 *. unit, sign, unit *. 0.1)
- ["6", ..input] ->
- parse_float(input, number +. 6.0 *. unit, sign, unit *. 0.1)
- ["7", ..input] ->
- parse_float(input, number +. 7.0 *. unit, sign, unit *. 0.1)
- ["8", ..input] ->
- parse_float(input, number +. 8.0 *. unit, sign, unit *. 0.1)
- ["9", ..input] ->
- parse_float(input, number +. 9.0 *. unit, sign, unit *. 0.1)
-
- ["e", "+", ..input] -> parse_exponent(input, number, sign, 0, Positive)
- ["e", "-", ..input] -> parse_exponent(input, number, sign, 0, Negative)
- ["e", ..input] -> parse_exponent(input, number, sign, 0, Positive)
- ["E", "+", ..input] -> parse_exponent(input, number, sign, 0, Positive)
- ["E", "-", ..input] -> parse_exponent(input, number, sign, 0, Negative)
- ["E", ..input] -> parse_exponent(input, number, sign, 0, Positive)
-
- // Anything else and the number is terminated
- input -> {
- let number = case sign {
- Positive -> number
- Negative -> number *. -1.0
- }
- Ok(#(Float(number), input))
- }
- }
-}
-
-fn parse_string(input: Tokens, string: String) -> Parsed(Toml) {
- case input {
- ["\"", ..input] -> Ok(#(String(string), input))
- ["\\", "t", ..input] -> parse_string(input, string <> "\t")
- ["\\", "n", ..input] -> parse_string(input, string <> "\n")
- ["\\", "r", ..input] -> parse_string(input, string <> "\r")
- ["\\", "\"", ..input] -> parse_string(input, string <> "\"")
- ["\\", "\\", ..input] -> parse_string(input, string <> "\\")
- [] -> Error(Unexpected("EOF", "\""))
- ["\n", ..] -> Error(Unexpected("\n", "\""))
- ["\r\n", ..] -> Error(Unexpected("\r\n", "\""))
- [g, ..input] -> parse_string(input, string <> g)
- }
-}
-
-fn parse_multi_line_string(input: Tokens, string: String) -> Parsed(Toml) {
- case input {
- ["\"", "\"", "\"", ..input] -> Ok(#(String(string), input))
- ["\\", "\n", ..input] ->
- parse_multi_line_string(skip_whitespace(input), string)
- ["\\", "\r\n", ..input] ->
- parse_multi_line_string(skip_whitespace(input), string)
- ["\r\n", ..input] if string == "" -> parse_multi_line_string(input, string)
- ["\n", ..input] if string == "" -> parse_multi_line_string(input, string)
- ["\r\n", ..input] if string == "" -> parse_multi_line_string(input, string)
- ["\\", "t", ..input] -> parse_multi_line_string(input, string <> "\t")
- ["\\", "n", ..input] -> parse_multi_line_string(input, string <> "\n")
- ["\\", "r", ..input] -> parse_multi_line_string(input, string <> "\r")
- ["\\", "\"", ..input] -> parse_multi_line_string(input, string <> "\"")
- ["\\", "\\", ..input] -> parse_multi_line_string(input, string <> "\\")
- [] -> Error(Unexpected("EOF", "\""))
- [g, ..input] -> parse_multi_line_string(input, string <> g)
- }
-}
-
-fn parse_multi_line_literal_string(
- input: Tokens,
- string: String,
-) -> Parsed(Toml) {
- case input {
- [] -> Error(Unexpected("EOF", "\""))
- ["'", "'", "'", "'", ..] -> Error(Unexpected("''''", "'''"))
- ["'", "'", "'", ..input] -> Ok(#(String(string), input))
- ["\n", ..input] if string == "" ->
- parse_multi_line_literal_string(input, string)
- ["\r\n", ..input] if string == "" ->
- parse_multi_line_literal_string(input, string)
- [g, ..input] -> parse_multi_line_literal_string(input, string <> g)
- }
-}
-
-fn parse_literal_string(input: Tokens, string: String) -> Parsed(Toml) {
- case input {
- [] -> Error(Unexpected("EOF", "\""))
- ["\n", ..] -> Error(Unexpected("\n", "'"))
- ["\r\n", ..] -> Error(Unexpected("\r\n", "'"))
- ["'", ..input] -> Ok(#(String(string), input))
- [g, ..input] -> parse_literal_string(input, string <> g)
- }
-}
-
-fn reverse_arrays_of_tables(toml: Toml) -> Toml {
- case toml {
- ArrayOfTables(tables) ->
- ArrayOfTables(reverse_arrays_of_tables_array(tables, []))
-
- Table(table) -> Table(reverse_arrays_of_tables_table(table))
-
- _ -> toml
- }
-}
-
-fn reverse_arrays_of_tables_table(table: Map(String, Toml)) -> Map(String, Toml) {
- map.map_values(table, fn(_, v) { reverse_arrays_of_tables(v) })
-}
-
-fn reverse_arrays_of_tables_array(
- array: List(Map(String, Toml)),
- acc: List(Map(String, Toml)),
-) -> List(Map(String, Toml)) {
- case array {
- [] -> acc
- [first, ..rest] -> {
- let first = reverse_arrays_of_tables_table(first)
- reverse_arrays_of_tables_array(rest, [first, ..acc])
- }
- }
-}
-
-fn parse_time_minute(input: Tokens, hours: Int) -> Parsed(Toml) {
- use minutes, input <- do(parse_number_under_60(input, "minutes"))
- use #(seconds, ms), input <- do(parse_time_s_ms(input))
- let time = TimeValue(hours, minutes, seconds, ms)
- Ok(#(Time(time), input))
-}
-
-fn parse_hour_minute(input: Tokens) -> Parsed(#(Int, Int)) {
- use hours, input <- do(case input {
- ["0", "0", ":", ..input] -> Ok(#(0, input))
- ["0", "1", ":", ..input] -> Ok(#(1, input))
- ["0", "2", ":", ..input] -> Ok(#(2, input))
- ["0", "3", ":", ..input] -> Ok(#(3, input))
- ["0", "4", ":", ..input] -> Ok(#(4, input))
- ["0", "5", ":", ..input] -> Ok(#(5, input))
- ["0", "6", ":", ..input] -> Ok(#(6, input))
- ["0", "7", ":", ..input] -> Ok(#(7, input))
- ["0", "8", ":", ..input] -> Ok(#(8, input))
- ["0", "9", ":", ..input] -> Ok(#(9, input))
- ["1", "0", ":", ..input] -> Ok(#(10, input))
- ["1", "1", ":", ..input] -> Ok(#(11, input))
- ["1", "2", ":", ..input] -> Ok(#(12, input))
- ["1", "3", ":", ..input] -> Ok(#(13, input))
- ["1", "4", ":", ..input] -> Ok(#(14, input))
- ["1", "5", ":", ..input] -> Ok(#(15, input))
- ["1", "6", ":", ..input] -> Ok(#(16, input))
- ["1", "7", ":", ..input] -> Ok(#(17, input))
- ["1", "8", ":", ..input] -> Ok(#(18, input))
- ["1", "9", ":", ..input] -> Ok(#(19, input))
- ["2", "0", ":", ..input] -> Ok(#(20, input))
- ["2", "1", ":", ..input] -> Ok(#(21, input))
- ["2", "2", ":", ..input] -> Ok(#(22, input))
- ["2", "3", ":", ..input] -> Ok(#(23, input))
- [g, ..] -> Error(Unexpected(g, "time"))
- [] -> Error(Unexpected("EOF", "time"))
- })
-
- use minutes, input <- do(parse_number_under_60(input, "minutes"))
- Ok(#(#(hours, minutes), input))
-}
-
-fn parse_time_value(input: Tokens) -> Parsed(Time) {
- use #(hours, minutes), input <- do(parse_hour_minute(input))
- use #(seconds, ms), input <- do(parse_time_s_ms(input))
- let time = TimeValue(hours, minutes, seconds, ms)
- Ok(#(time, input))
-}
-
-fn parse_time_s_ms(input: Tokens) -> Parsed(#(Int, Int)) {
- case input {
- [":", ..input] -> {
- use seconds, input <- do(parse_number_under_60(input, "seconds"))
- case input {
- [".", ..input] -> parse_time_ms(input, seconds, 0)
- _ -> Ok(#(#(seconds, 0), input))
- }
- }
-
- _ -> Ok(#(#(0, 0), input))
- }
-}
-
-fn parse_time_ms(input: Tokens, seconds: Int, ms: Int) -> Parsed(#(Int, Int)) {
- case input {
- ["0", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 0)
- ["1", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 1)
- ["2", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 2)
- ["3", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 3)
- ["4", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 4)
- ["5", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 5)
- ["6", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 6)
- ["7", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 7)
- ["8", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 8)
- ["9", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 9)
-
- // Anything else and the number is terminated
- _ -> Ok(#(#(seconds, ms), input))
- }
-}
-
-fn parse_number_under_60(input: Tokens, expected: String) -> Parsed(Int) {
- case input {
- ["0", "0", ..input] -> Ok(#(0, input))
- ["0", "1", ..input] -> Ok(#(1, input))
- ["0", "2", ..input] -> Ok(#(2, input))
- ["0", "3", ..input] -> Ok(#(3, input))
- ["0", "4", ..input] -> Ok(#(4, input))
- ["0", "5", ..input] -> Ok(#(5, input))
- ["0", "6", ..input] -> Ok(#(6, input))
- ["0", "7", ..input] -> Ok(#(7, input))
- ["0", "8", ..input] -> Ok(#(8, input))
- ["0", "9", ..input] -> Ok(#(9, input))
- ["1", "0", ..input] -> Ok(#(10, input))
- ["1", "1", ..input] -> Ok(#(11, input))
- ["1", "2", ..input] -> Ok(#(12, input))
- ["1", "3", ..input] -> Ok(#(13, input))
- ["1", "4", ..input] -> Ok(#(14, input))
- ["1", "5", ..input] -> Ok(#(15, input))
- ["1", "6", ..input] -> Ok(#(16, input))
- ["1", "7", ..input] -> Ok(#(17, input))
- ["1", "8", ..input] -> Ok(#(18, input))
- ["1", "9", ..input] -> Ok(#(19, input))
- ["2", "0", ..input] -> Ok(#(20, input))
- ["2", "1", ..input] -> Ok(#(21, input))
- ["2", "2", ..input] -> Ok(#(22, input))
- ["2", "3", ..input] -> Ok(#(23, input))
- ["2", "4", ..input] -> Ok(#(24, input))
- ["2", "5", ..input] -> Ok(#(25, input))
- ["2", "6", ..input] -> Ok(#(26, input))
- ["2", "7", ..input] -> Ok(#(27, input))
- ["2", "8", ..input] -> Ok(#(28, input))
- ["2", "9", ..input] -> Ok(#(29, input))
- ["3", "0", ..input] -> Ok(#(30, input))
- ["3", "1", ..input] -> Ok(#(31, input))
- ["3", "2", ..input] -> Ok(#(32, input))
- ["3", "3", ..input] -> Ok(#(33, input))
- ["3", "4", ..input] -> Ok(#(34, input))
- ["3", "5", ..input] -> Ok(#(35, input))
- ["3", "6", ..input] -> Ok(#(36, input))
- ["3", "7", ..input] -> Ok(#(37, input))
- ["3", "8", ..input] -> Ok(#(38, input))
- ["3", "9", ..input] -> Ok(#(39, input))
- ["4", "0", ..input] -> Ok(#(40, input))
- ["4", "1", ..input] -> Ok(#(41, input))
- ["4", "2", ..input] -> Ok(#(42, input))
- ["4", "3", ..input] -> Ok(#(43, input))
- ["4", "4", ..input] -> Ok(#(44, input))
- ["4", "5", ..input] -> Ok(#(45, input))
- ["4", "6", ..input] -> Ok(#(46, input))
- ["4", "7", ..input] -> Ok(#(47, input))
- ["4", "8", ..input] -> Ok(#(48, input))
- ["4", "9", ..input] -> Ok(#(49, input))
- ["5", "0", ..input] -> Ok(#(50, input))
- ["5", "1", ..input] -> Ok(#(51, input))
- ["5", "2", ..input] -> Ok(#(52, input))
- ["5", "3", ..input] -> Ok(#(53, input))
- ["5", "4", ..input] -> Ok(#(54, input))
- ["5", "5", ..input] -> Ok(#(55, input))
- ["5", "6", ..input] -> Ok(#(56, input))
- ["5", "7", ..input] -> Ok(#(57, input))
- ["5", "8", ..input] -> Ok(#(58, input))
- ["5", "9", ..input] -> Ok(#(59, input))
-
- [g, ..] -> Error(Unexpected(g, expected))
- [] -> Error(Unexpected("EOF", expected))
- }
-}
-
-fn parse_date(input: Tokens, year: Int) -> Parsed(Toml) {
- case input {
- ["0", "1", "-", ..input] -> parse_date_day(input, year, 1)
- ["0", "2", "-", ..input] -> parse_date_day(input, year, 2)
- ["0", "3", "-", ..input] -> parse_date_day(input, year, 3)
- ["0", "4", "-", ..input] -> parse_date_day(input, year, 4)
- ["0", "5", "-", ..input] -> parse_date_day(input, year, 5)
- ["0", "6", "-", ..input] -> parse_date_day(input, year, 6)
- ["0", "7", "-", ..input] -> parse_date_day(input, year, 7)
- ["0", "8", "-", ..input] -> parse_date_day(input, year, 8)
- ["0", "9", "-", ..input] -> parse_date_day(input, year, 9)
- ["1", "0", "-", ..input] -> parse_date_day(input, year, 10)
- ["1", "1", "-", ..input] -> parse_date_day(input, year, 11)
- ["1", "2", "-", ..input] -> parse_date_day(input, year, 12)
-
- [g, ..] -> Error(Unexpected(g, "date month"))
- [] -> Error(Unexpected("EOF", "date month"))
- }
-}
-
-fn parse_date_day(input: Tokens, year: Int, month: Int) -> Parsed(Toml) {
- case input {
- ["0", "1", ..input] -> parse_date_end(input, year, month, 1)
- ["0", "2", ..input] -> parse_date_end(input, year, month, 2)
- ["0", "3", ..input] -> parse_date_end(input, year, month, 3)
- ["0", "4", ..input] -> parse_date_end(input, year, month, 4)
- ["0", "5", ..input] -> parse_date_end(input, year, month, 5)
- ["0", "6", ..input] -> parse_date_end(input, year, month, 6)
- ["0", "7", ..input] -> parse_date_end(input, year, month, 7)
- ["0", "8", ..input] -> parse_date_end(input, year, month, 8)
- ["0", "9", ..input] -> parse_date_end(input, year, month, 9)
- ["1", "0", ..input] -> parse_date_end(input, year, month, 10)
- ["1", "1", ..input] -> parse_date_end(input, year, month, 11)
- ["1", "2", ..input] -> parse_date_end(input, year, month, 12)
- ["1", "3", ..input] -> parse_date_end(input, year, month, 13)
- ["1", "4", ..input] -> parse_date_end(input, year, month, 14)
- ["1", "5", ..input] -> parse_date_end(input, year, month, 15)
- ["1", "6", ..input] -> parse_date_end(input, year, month, 16)
- ["1", "7", ..input] -> parse_date_end(input, year, month, 17)
- ["1", "8", ..input] -> parse_date_end(input, year, month, 18)
- ["1", "9", ..input] -> parse_date_end(input, year, month, 19)
- ["2", "0", ..input] -> parse_date_end(input, year, month, 20)
- ["2", "1", ..input] -> parse_date_end(input, year, month, 21)
- ["2", "2", ..input] -> parse_date_end(input, year, month, 22)
- ["2", "3", ..input] -> parse_date_end(input, year, month, 23)
- ["2", "4", ..input] -> parse_date_end(input, year, month, 24)
- ["2", "5", ..input] -> parse_date_end(input, year, month, 25)
- ["2", "6", ..input] -> parse_date_end(input, year, month, 26)
- ["2", "7", ..input] -> parse_date_end(input, year, month, 27)
- ["2", "8", ..input] -> parse_date_end(input, year, month, 28)
- ["2", "9", ..input] -> parse_date_end(input, year, month, 29)
- ["3", "0", ..input] -> parse_date_end(input, year, month, 30)
- ["3", "1", ..input] -> parse_date_end(input, year, month, 31)
-
- [g, ..] -> Error(Unexpected(g, "date day"))
- [] -> Error(Unexpected("EOF", "date day"))
- }
-}
-
-fn parse_date_end(
- input: Tokens,
- year: Int,
- month: Int,
- day: Int,
-) -> Parsed(Toml) {
- let date = DateValue(year, month, day)
- case input {
- [" ", ..input] | ["T", ..input] -> {
- use time, input <- do(parse_time_value(input))
- use offset, input <- do(parse_offset(input))
- Ok(#(DateTime(DateTimeValue(date, time, offset)), input))
- }
-
- _ -> Ok(#(Date(date), input))
- }
-}
-
-fn parse_offset(input: Tokens) -> Parsed(Offset) {
- case input {
- ["Z", ..input] -> Ok(#(Offset(Positive, 0, 0), input))
- ["+", ..input] -> parse_offset_hours(input, Positive)
- ["-", ..input] -> parse_offset_hours(input, Negative)
- _ -> Ok(#(Local, input))
- }
-}
-
-fn parse_offset_hours(input: Tokens, sign: Sign) -> Parsed(Offset) {
- use #(hours, minutes), input <- do(parse_hour_minute(input))
- Ok(#(Offset(sign, hours, minutes), input))
-}