Packages
stellar_sdk
0.18.1
0.23.0
0.22.0
0.21.2
0.21.1
0.21.0
0.20.0
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.1
0.13.0
0.12.0
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Elixir SDK for the Stellar network.
Current section
Files
Jump to
Current section
Files
lib/horizon/mapping.ex
defmodule Stellar.Horizon.Mapping do
@moduledoc """
Takes a result map or list of maps from Horizon response and returns a struct
(e.g. `%Horizon.Transaction{}`) or list of structs.
"""
@type attr_value :: any()
@type attr_type ::
:integer
| :float
| :date_time
| {:map, Keyword.t()}
| {:struct, module()}
| {:list, atom(), Keyword.t() | module()}
@spec build(module :: struct(), attrs :: map()) :: struct()
def build(module, attrs) do
attrs =
module
|> Map.from_struct()
|> Map.keys()
|> (&Map.take(attrs, &1)).()
struct!(module, attrs)
end
@spec parse(module :: struct(), mapping :: Keyword.t()) :: struct()
def parse(module, []), do: module
def parse(module, [{attr, type} | attrs]) do
value = Map.get(module, attr)
parsed_value = do_parse(type, value)
module
|> Map.put(attr, parsed_value)
|> parse(attrs)
end
@spec do_parse(type :: attr_type(), value :: attr_value()) :: attr_value()
defp do_parse(:integer, value) when is_bitstring(value), do: String.to_integer(value)
defp do_parse(:float, value) when is_bitstring(value), do: String.to_float(value)
defp do_parse(:date_time, value) when is_bitstring(value) do
case DateTime.from_iso8601(value) do
{:ok, date_time, _offset} -> date_time
_error -> value
end
end
defp do_parse({:map, mapping}, value) when is_map(value) do
Enum.reduce(mapping, value, fn {key, type}, acc ->
acc
|> Map.get(key)
|> (&do_parse(type, &1)).()
|> (&Map.put(acc, key, &1)).()
end)
end
defp do_parse({:struct, module}, value) when not is_nil(value), do: module.new(value)
defp do_parse({:list, :map, mapping}, values) when is_list(values) do
Enum.map(values, &do_parse({:map, mapping}, &1))
end
defp do_parse({:list, :struct, module}, values) when is_list(values) do
Enum.map(values, &module.new(&1))
end
defp do_parse(_type, value), do: value
end