Using :eph from now on to store ephemeral data like :sibling_with. Additionally added cleaning up :eph before saving to db. And renamed InternalTree.Basic to InternalTree.RawInternalBasic to make clear that it contains function for an intermediary tree structure.
57 lines
1.3 KiB
Elixir
57 lines
1.3 KiB
Elixir
defmodule Outlook.Articles.InternalTree do
|
|
use Ecto.Type
|
|
|
|
alias Outlook.InternalTree.InternalNode
|
|
alias Outlook.InternalTree.TranslationUnit
|
|
alias Outlook.InternalTree.Basic
|
|
|
|
def type, do: :string
|
|
|
|
def cast(tree) when is_list(tree) do
|
|
{:ok, tree}
|
|
end
|
|
|
|
def cast(_), do: :error
|
|
|
|
def load(tree) when is_binary(tree) do
|
|
{:ok, Jason.decode!(tree, keys: :atoms!) |> from_json}
|
|
end
|
|
|
|
def dump(tree) when is_list(tree) do
|
|
{:ok, Basic.clean_eph(tree) |> Jason.encode!()}
|
|
end
|
|
|
|
def dump(_), do: :error
|
|
|
|
|
|
defp from_json([%{status: _} = node | rest]) do
|
|
[ %TranslationUnit{
|
|
status: String.to_atom(node.status),
|
|
uuid: node.uuid,
|
|
content: node.content
|
|
} | from_json(rest) ]
|
|
end
|
|
|
|
defp from_json([%{type: "element"} = node | rest]) do
|
|
[ %InternalNode{
|
|
name: node.name,
|
|
attributes: node.attributes,
|
|
type: String.to_atom(node.type),
|
|
uuid: node.uuid,
|
|
content: from_json(node.content)
|
|
} | from_json(rest) ]
|
|
end
|
|
|
|
defp from_json([%{type: _} = node | rest]) do
|
|
[ %InternalNode{
|
|
name: node.name,
|
|
attributes: node.attributes,
|
|
type: String.to_atom(node.type),
|
|
uuid: node.uuid,
|
|
content: node.content
|
|
} | from_json(rest) ]
|
|
end
|
|
|
|
defp from_json([]), do: []
|
|
end
|