Packages

`Retroper` is the tool to convert between `Estructura.Aston` instances, _XML_ and _JSON_.

Current section

Files

Jump to
retroper lib retroper.ex
Raw

lib/retroper.ex

defmodule Retroper do
@moduledoc """
`Retroper` is the tool to convert between `Estructura.Aston` instances, _XML_ and _JSON_.
To make it isomorphic, _JSON_ is supposed to be presented in the form of `Estructura.Aston`-like
nested objects, all having `name`, `attributes`, and `content` fields.
"""
alias XmlToMap, as: XmlMap
{:ok, model} = :erlsom.compile_xsd_file(~s"specs/dealconfirmation_42.xsd")
@model model
def default_model, do: @model
def json_to_xml(json, model \\ @model, validate \\ true, format \\ :none)
when is_binary(json) do
with {:ok, map} <- Jason.decode(json), do: map_to_xml(map, model, validate, format)
end
def xml_to_xml(xml, model \\ @model, validate \\ true, format \\ :none) when is_binary(xml) do
with %{} = map <- XmlMap.nested_map(xml), do: map_to_xml(map, model, validate, format)
end
def xml_to_json(xml, model \\ @model, validate \\ true, format \\ :none) when is_binary(xml) do
with %{} = map <- XmlMap.nested_map(xml), do: map_to_json(map, model, validate, format)
end
def json_to_json(json, model \\ @model, validate \\ true, format \\ :none)
when is_binary(json) do
with {:ok, %{} = map} <- Jason.decode(json), do: map_to_json(map, model, validate, format)
end
def map_to_json(map, model \\ @model, validate \\ true, format \\ :none) do
with {:ok, tree} <- Estructura.Aston.coerce(map),
ast = Estructura.Aston.to_ast(tree),
xml = XmlBuilder.generate([:xml_decl, ast], standalone: true, format: format),
{:ok, _, _} <- if(validate, do: :erlsom.scan(xml, model), else: {:ok, :ok, :ok}),
do: Jason.encode(tree)
end
def map_to_xml(map, model \\ @model, validate \\ true, format \\ :none) do
with {:ok, tree} <- Estructura.Aston.coerce(map),
ast = Estructura.Aston.to_ast(tree),
xml = XmlBuilder.generate([:xml_decl, ast], standalone: true, format: format),
{:ok, _, _} <- if(validate, do: :erlsom.scan(xml, model), else: {:ok, :ok, :ok}),
do: {:ok, xml}
end
for from <- ~w|json map xml|a, to <- ~w|json xml| do
def unquote(:"#{from}_to_#{to}!")(map, model \\ @model, validate \\ true, format \\ :none) do
case unquote(:"#{from}_to_#{to}")(map, model, validate, format) do
{:ok, result} ->
result
{:error, reason} ->
raise ArgumentError,
message:
"Cannot convert `#{unquote(from)}` to `#{unquote(to)}, reason: #{inspect(reason)}"
end
end
end
end