defmodule Localizator.Parser.YAML do @indent " " @extensions ["yml", "yaml"] @type contents :: String.t() @type data :: map @type extensions :: [String.t()] @behaviour Localizator.Parser.Base @impl true @spec parse(contents) :: {:ok, data} | {:error, atom | Jason.DecodeError.t()} def parse(contents) do YamlElixir.read_from_string(contents) end @impl true @spec generate(data) :: {:ok, contents} | {:error, any} def generate(data) do {:ok, to_yaml(data)} end defp to_yaml(data, indentation \\ "") do data |> Map.keys() |> Enum.map(fn key -> Map.fetch!(data, key) |> value_to_yaml(key, indentation) end) |> Enum.join("\n") end defp value_to_yaml(value, key, indentation) when is_number(value) or is_bitstring(value), do: "#{indentation}#{key}: #{value}" defp value_to_yaml(value, key, indentation) when is_map(value), do: "#{indentation}#{key}:\n#{to_yaml(value, "#{indentation}#{@indent}")}" @impl true @spec extensions() :: {:ok, extensions} def extensions(), do: {:ok, @extensions} end