Skip to content

Commit

Permalink
Move map transforming to separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
nikolauska committed Nov 14, 2017
1 parent 0f231d4 commit 2f2b2cc
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 70 deletions.
84 changes: 14 additions & 70 deletions lib/toml_elixir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ defmodule TomlElixir do
* `TomlElixir.parse_file/2`
* `TomlElixir.parse_file!/2`
"""
alias TomlElixir.Mapper

@typedoc """
Toml value is a tuple with type and actual value
"""
Expand Down Expand Up @@ -150,7 +152,7 @@ defmodule TomlElixir do
{:ok, list} <- parser(tokens)
do
if to_map?(opts) do
{:ok, to_map(list)}
{:ok, Mapper.parse(list)}
else
{:ok, list}
end
Expand Down Expand Up @@ -210,11 +212,15 @@ defmodule TomlElixir do
defp to_map?(opts) do
cond do
Keyword.get(opts, :no_parse) == true ->
IO.puts("#{__MODULE__}: no_parse option is deprecated, " <>
IO.puts("TomlElixir: no_parse option is deprecated, " <>
"please use new to_map: false option")
false
Keyword.get(opts, :to_map) == false -> false
true -> true

Keyword.get(opts, :to_map) == false ->
false

true ->
true
end
end

Expand Down Expand Up @@ -244,70 +250,8 @@ defmodule TomlElixir do
do: {:ok, tokens}
defp erl_result_parse({:ok, list}),
do: {:ok, list}
defp erl_result_parse({:error, {line, _, err}}),
do: {:error, "Error on line #{line}: #{err}"}
defp erl_result_parse({:error, {line, _, {err, msg}}, _}),
do: {:error, "Error on line #{line}: #{err} #{msg}"}

# Turn toml tuple list to map
@spec to_map(toml_return) :: map
@spec to_map(toml_return, [] | [any] | map) :: map
defp to_map(val),
do: to_map(val, %{})
defp to_map(val, []),
do: [to_map(val, %{})]
defp to_map(val, list) when is_list(list),
do: List.update_at(list, -1, &(to_map(val, &1)))
defp to_map([{:group, idents, values} | tail], map),
do: to_map(tail, group(idents, values, map))
defp to_map([{:multi, idents, values} | tail], map),
do: to_map(tail, multi(idents, values, map))
defp to_map([{{:identifier, key}, values} | tail], map) when is_list(values),
do: to_map(tail, put(map, key, value(values)))
defp to_map([{{:identifier, key}, val} | tail], map),
do: to_map(tail, put(map, key, value(val)))
defp to_map([], map),
do: map

# Turn group tuple to map
@spec group([toml_ident], [toml_key_val], [any] | map) :: map | [any]
defp group(idents, values, []),
do: [group(idents, values, %{})]
defp group(idents, values, list) when is_list(list),
do: List.update_at(list, -1, &group(idents, values, &1))
defp group([{:identifier, key} | tail], values, map),
do: put(map, key, group(tail, values, get(map, key, %{})))
defp group([], values, map),
do: to_map(values, map)

# Turn multi tuple to map
@spec multi([toml_ident], [toml_key_val], map) :: map
defp multi([{:identifier, key} | []], values, map),
do: put(map, key, to_map(values, insert_end(map, key, %{})))
defp multi([{:identifier, key} | tail], values, map),
do: put(map, key, multi(tail, values, get(map, key, %{})))

# Parse value from toml value tuple
@spec value(toml_value | [toml_value]) :: any
defp value([]), do: []
defp value([head | tail]), do: [value(head) | value(tail)]
defp value({:string, val}), do: "#{val}"
defp value({:datetime, val}), do: val
defp value({:number, val}), do: val
defp value({:boolean, val}), do: val

# Add value to end of the list
@spec insert_end(map, binary, any) :: [map]
defp insert_end(map, key, value),
do: List.insert_at(get(map, key, []), -1, value)

# Get value from map
@spec get(map, binary, any) :: any
defp get(map, key, default),
do: Map.get(map, "#{key}", default)

# Put value to map
@spec put(map, binary, any) :: map
defp put(map, key, value),
do: Map.put(map, "#{key}", value)
defp erl_result_parse({:error, {_line, _, err}}),
do: {:error, "Error: #{err}"}
defp erl_result_parse({:error, {_line, _, {err, msg}}, _}),
do: {:error, "#{err} #{msg}"}
end
72 changes: 72 additions & 0 deletions lib/toml_elixir/mapper.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
defmodule TomlElixir.Mapper do

@doc """
Parse list of values to map
"""
@spec parse(TomlElixir.toml_return) :: map
def parse(toml) do
to_map(toml)
end

# Turn toml tuple list to map
@spec to_map(TomlElixir.toml_return) :: map
@spec to_map(TomlElixir.toml_return, [] | [any] | map) :: map
defp to_map(val),
do: to_map(val, %{})
defp to_map(val, []),
do: [to_map(val, %{})]
defp to_map(val, list) when is_list(list),
do: List.update_at(list, -1, &(to_map(val, &1)))
defp to_map([{:group, idents, values} | tail], map),
do: to_map(tail, group(idents, values, map))
defp to_map([{:multi, idents, values} | tail], map),
do: to_map(tail, multi(idents, values, map))
defp to_map([{{:identifier, key}, values} | tail], map) when is_list(values),
do: to_map(tail, put(map, key, value(values)))
defp to_map([{{:identifier, key}, val} | tail], map),
do: to_map(tail, put(map, key, value(val)))
defp to_map([], map),
do: map

# Turn group tuple to map
@spec group([TomlElixir.toml_ident], [TomlElixir.toml_key_val], [any] | map) :: map | [any]
defp group(idents, values, []),
do: [group(idents, values, %{})]
defp group(idents, values, list) when is_list(list),
do: List.update_at(list, -1, &group(idents, values, &1))
defp group([{:identifier, key} | tail], values, map),
do: put(map, key, group(tail, values, get(map, key, %{})))
defp group([], values, map),
do: to_map(values, map)

# Turn multi tuple to map
@spec multi([TomlElixir.toml_ident], [TomlElixir.toml_key_val], map) :: map
defp multi([{:identifier, key} | []], values, map),
do: put(map, key, to_map(values, insert_end(map, key, %{})))
defp multi([{:identifier, key} | tail], values, map),
do: put(map, key, multi(tail, values, get(map, key, %{})))

# Parse value from toml value tuple
@spec value(TomlElixir.toml_value | [TomlElixir.toml_value]) :: any
defp value([]), do: []
defp value([head | tail]), do: [value(head) | value(tail)]
defp value({:string, val}), do: "#{val}"
defp value({:datetime, val}), do: val
defp value({:number, val}), do: val
defp value({:boolean, val}), do: val

# Add value to end of the list
@spec insert_end(map, binary, any) :: [map]
defp insert_end(map, key, value),
do: List.insert_at(get(map, key, []), -1, value)

# Get value from map
@spec get(map, binary, any) :: any
defp get(map, key, default),
do: Map.get(map, "#{key}", default)

# Put value to map
@spec put(map, binary, any) :: map
defp put(map, key, value),
do: Map.put(map, "#{key}", value)
end

0 comments on commit 2f2b2cc

Please sign in to comment.