defmodule YamlElixir do alias YamlElixir.Mapper @yamerl_options [ detailed_constr: true, str_node_as_binary: true, keep_duplicate_keys: true ] def read_all_from_file!(path, options \\ []) do case read_all_from_file(path, options) do {:ok, result} -> result {:error, error} -> raise error end end def read_all_from_file(path, options \\ []), do: do_read(:file, path, options) def read_from_file!(path, options \\ []) do case read_from_file(path, options) do {:ok, result} -> result {:error, error} -> raise error end end def read_from_file(path, options \\ []), do: do_read(:file, path, Keyword.put(options, :one_result, true)) def read_all_from_string!(string, options \\ []) do case read_all_from_string(string, options) do {:ok, result} -> result {:error, error} -> raise error end end def read_all_from_string(string, options \\ []), do: do_read(:string, string, options) def read_from_string!(string, options \\ []) do case read_from_string(string, options) do {:ok, result} -> result {:error, error} -> raise error end end def read_from_string(string, options \\ []), do: do_read(:string, string, Keyword.put(options, :one_result, true)) defp do_read(type, source, options) do {:ok, prepare_and_read(type, source, options)} catch {:yamerl_exception, [{_, _, message, _, _, :file_open_failure, _, _}]} -> {:error, %YamlElixir.FileNotFoundError{message: List.to_string(message)}} {:yamerl_exception, [error | _]} -> {:error, YamlElixir.ParsingError.from_yamerl(error)} _, _ -> {:error, %YamlElixir.ParsingError{message: "malformed yaml"}} end defp prepare_and_read(type, source, options) do ensure_yamerl_started() options |> merge_options() |> read(type, source) end defp read(options, type, source) do type |> yamerl_constr(source, options) |> extract_data(options) |> Mapper.process(options) end defp merge_options(options), do: Keyword.merge(options, @yamerl_options) defp yamerl_constr(:file, path, options), do: :yamerl_constr.file(path, options) defp yamerl_constr(:string, data, options), do: :yamerl_constr.string(data, options) defp extract_data(data, options) do options |> Keyword.get(:one_result) |> maybe_take_last(data) end defp maybe_take_last(true, data), do: List.last(data) defp maybe_take_last(_, data), do: data defp ensure_yamerl_started, do: Application.start(:yamerl) end