Packages
rustler
0.0.7
0.38.0
0.37.3
0.37.1
0.37.0
retired
0.36.2
0.36.1
0.36.0
0.35.1
0.35.0
0.34.0
0.33.0
0.32.1
0.31.0
0.30.0
0.29.1
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.2
0.22.1
0.22.0
0.22.0-rc.2
0.22.0-rc.1
0.22.0-rc.0
0.21.1
0.21.0
0.20.0
0.19.1
0.19.0
0.18.0
0.17.1
0.17.0
0.16.0
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.1
0.1.0
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Mix compiler and runtime helpers for Rustler.
Current section
Files
Jump to
Current section
Files
lib/toml_parser.ex
defmodule Rustler.TomlParser do
# (very) Incomplete parser for TOML (https://github.com/toml-lang/toml)
# Should be made into a separate project in the future. For now it is
# just used to extract version numbers from Cargo.toml files.
def parse(text) do
{:ok, tokens, _test_chars} = text |> to_char_list |> :toml_lexer.string
{:ok, parsed} = :toml_parser.parse(tokens)
collect(parsed, [])
end
# Pass 1: Collect
def collect([{:kv, _, _} | _] = items, acc) do
{rest, res_items} = collect_keys(items, [])
collect(rest, [{:table, [], res_items} | acc])
end
def collect([{:table, path} | items], acc) do
{rest, res_items, path_proc} = collect_table(path, items)
collect(rest, [{:table, path_proc, res_items} | acc])
end
def collect([{:table_array, path} | items], acc) do
{rest, res_items, path_proc} = collect_table(path, items)
collect(rest, [{:table_array, path_proc, res_items} | acc])
end
def collect([], acc) do
Enum.reverse(acc)
end
def collect_table(path, items) do
{rest, res_items} = collect_keys(items, [])
path_proc = Enum.map(path, &proc_key(&1))
{rest, res_items, path_proc}
end
def collect_keys([{:kv, key, val} | rest], acc) do
collect_keys(rest, [{proc_key(key), proc_val(val)} | acc])
end
def collect_keys(rest, acc) do
{rest, acc}
end
def proc_key({:bare, name}) do
name
end
def proc_val({:val_basic, raw_str}) do
# TODO: Escapes
:binary.part(raw_str, 1, byte_size(raw_str) - 2)
end
def proc_val({:val_integer, raw_num}) do
{num, ""} = Integer.parse(raw_num)
num
end
def proc_val({:array, arr_ast}) do
# TODO: Validate types
Enum.map(arr_ast, fn
item -> proc_val(item)
end)
end
# Pass 2: Fuck it for now
def get_table_vals(data, path) do
found = Enum.find(data, fn
{:table, inner_path, values} -> path == inner_path
_ -> false
end)
with {:table, _path, vals} <- found, do: vals
end
def get_keys_key(nil, _), do: nil
def get_keys_key(vals, key) do
case List.keyfind(vals, key, 0) do
{_key, val} -> val
_ -> nil
end
end
def get_table_val(data, path, key) do
vals = get_table_vals(data, path)
get_keys_key(vals, key)
end
end