hocon v0.1.8 Hocon View Source

This module pareses and decodes a hocon configuration string.

Example

iex(1)> conf = ~s(animal { favorite : "dog" }, key : """${animal.favorite} is my favorite animal""")
iex(2)> Hocon.decode(conf)
{:ok,
%{"animal" => %{"favorite" => "dog"}, "key" => "dog is my favorite animal"}}

Units format

The parser returns a map, because in Elixir it is a common use case to use pattern matching on maps to extract specific values and keys. Therefore the Hocon.decode/2 function returns a map. To support interpreting a value with some family of units, you can call some conversion functions like as_bytes/1.

Example

 iex> conf = ~s(limit : "512KB")
 iex> {:ok, %{"limit" => limit}} = Hocon.decode(conf)
 iex> Hocon.as_bytes(limit)
 524288

It is possible to access the unit formats by a keypath, as well:

Example

 iex> conf = ~s(a { b { c { limit : "512KB" } } })
 iex> {:ok, map} = Hocon.decode(conf)
 iex> Hocon.get_bytes(map, "a.b.c.limit")
 524288
 iex> Hocon.get_size(map, "a.b.c.limit")
 512000

Include

HOCON supports including of other configuration files. The default implmentation uses the file systems, which seems to be the most known use case. For other use cases you can implement the Hocon.Resolver behaviour and call the decode/2 function with file_resolver: MyResolver as an option.

Example

The file include-1.conf exists and has the following content:

{ x : 10, y : ${a.x} }

In the case we use the Hocon.FileResolver (which is the default as well):

iex> conf = ~s({ a : { include "./test/data/include-1" } })
iex> Hocon.decode(conf, file_resolver: Hocon.FileResolver)
{:ok, %{"a" => %{"x" => 10, "y" => 10}}}

To minimize the dependencies of other packages, you need to include the HoconUrlResolver if you want to load configuration from the internet:

def deps do
[
  {:hocon_url_resolver, "~> 0.1.0"}
]
end

or just implement a resolver like:

URL-Resolver with HTTPoison

  defmodule HoconUrlResolver do
  @behaviour Hocon.Resolver

  @spec exists?(Path.t()) :: boolean
  def exists?(url) do
    case HTTPoison.head(url) do
      {:ok, %HTTPoison.Response{status_code: 200}} -> true
      {:ok, %HTTPoison.Response{status_code: 404}} -> false
      {:error, _}                                  -> false
    end
  end

  def load(url) do
    case HTTPoison.get(url) do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> {:ok, body}
      {:ok, %HTTPoison.Response{status_code: 404}}             -> {:error, "not found"}
      {:error, %HTTPoison.Error{reason: reason}}               -> {:error, reason}
    end
  end

end

Link to this section Summary

Functions

Returns the size of the string by using the power of 2.

Returns the time of the string as milliseconds.

Returns the duration of the string as Hocon.Period.

Returns the size of the string by using the power of 10.

Parses and decodes a hocon string and returns a map

Similar to decode/2 except it will unwrap the error tuple and raise in case of errors.

Returns a value for the keypath from a map or a successfull parse HOCON string.

Same a get/3 but the value is interpreted like a number by using the power of 2.

Same a get/3 but the value is interpreted like a duration format in milliseconds.

Same a get/3 but the value is interpreted like a duration format in Hocon.Period.

Same a get/3 but the value is interpreted like a number by using the power of 10.

Link to this section Functions

Returns the size of the string by using the power of 2.

Example

iex> Hocon.as_bytes("512kb")
524288
iex> Hocon.as_bytes("125 gigabytes")
134217728000

Returns the time of the string as milliseconds.

Example

iex> Hocon.as_milliseconds("30s")
30000
iex> Hocon.as_milliseconds("10us")
0.01

Returns the duration of the string as Hocon.Period.

Example

iex> Hocon.as_period("3 weeks")
%Hocon.Period{days: 21, months: 0, years: 0}
iex> Hocon.as_period("14d")
%Hocon.Period{days: 14, months: 0, years: 0}

Returns the size of the string by using the power of 10.

Example

iex> Hocon.as_size("512kb")
512000
iex> Hocon.as_size("125 gigabytes")
125000000000
Link to this function

decode(string, opts \\ [])

View Source

Parses and decodes a hocon string and returns a map

options

  • :convert_numerically_indexed - if set to true then numerically-indexed objects are converted to arrays
  • :strict_conversion - if set to true then numerically-indexed objects are only converted to arrays if all keys are numbers
  • :file_resolver - set to the module, which is responsible for loading the file resources. The default is Hocon.FileResolver
  • :url_resolver - set to the module, which is responsible for loading the url resources. The default is Hocon.FileResolver

Example

iex> conf = ~s(animal { favorite : "dog" }, key : """${animal.favorite} is my favorite animal""")
iex> Hocon.decode(conf)
{:ok,
%{"animal" => %{"favorite" => "dog"}, "key" => "dog is my favorite animal"}}

Runtime-Configuration with HOCON

Use can use the HOCON-Parser as a Config.Provider to load configuration during boot:

defmodule HOCONConfigProvider do
  @behaviour Config.Provider

  require Logger

  # Let's pass the path to the HOCON file as config
  def init(path) when is_binary(path), do: path

  def load(config, path) do
    # We need to start any app we may depend on.
    {:ok, _} = Application.ensure_all_started(:hocon)
    {:ok, _} = Application.ensure_all_started(:logger)

    Logger.info("Reading runtime config from #{path}")

    conf = path |> File.read!() |> Hocon.decode!()

    runtime = [mailer_config(conf)] |> filter_nils()

    Config.Reader.merge(config, runtime)
  end

  defp mailer_config(%{"mailer" => %{"server" => server, "port" => port}}) do
    {JobsKliniken.Mailer, [server: server, port: port]}
  end
  defp mailer_config(%{}) do
    {JobsKliniken.Mailer, nil}
  end

  defp filter_nils(keyword) do
    Enum.reject(keyword, fn {_key, value} -> is_nil(value) end)
  end
end
Link to this function

decode!(string, opts \\ [])

View Source

Similar to decode/2 except it will unwrap the error tuple and raise in case of errors.

Link to this function

get(root, keypath, default \\ nil)

View Source

Returns a value for the keypath from a map or a successfull parse HOCON string.

Example

iex> conf = Hocon.decode!(~s(a { b { c : "10kb" } }))
%{"a" => %{"b" => %{"c" => "10kb"}}}
iex> Hocon.get(conf, "a.b.c")
"10kb"
iex> Hocon.get(conf, "a.b.d")
nil
iex> Hocon.get(conf, "a.b.d", "1kb")
"1kb"
Link to this function

get_bytes(root, keypath, default \\ nil)

View Source

Same a get/3 but the value is interpreted like a number by using the power of 2.

Example

iex> conf = Hocon.decode!(~s(a { b { c : "10kb" } }))
%{"a" => %{"b" => %{"c" => "10kb"}}}
iex> Hocon.get_bytes(conf, "a.b.c")
10240
iex> Hocon.get_bytes(conf, "a.b.d")
nil
iex> Hocon.get_bytes(conf, "a.b.d", 1024)
1024
Link to this function

get_milliseconds(root, keypath, default \\ nil)

View Source

Same a get/3 but the value is interpreted like a duration format in milliseconds.

Example

iex> conf = Hocon.decode!(~s(a { b { c : "30s" } }))
%{"a" => %{"b" => %{"c" => "30s"}}}
iex> Hocon.get_milliseconds(conf, "a.b.c")
30000
iex> Hocon.get_milliseconds(conf, "a.b.d")
nil
iex> Hocon.get_milliseconds(conf, "a.b.d", 1000)
1000
Link to this function

get_period(root, keypath, default \\ nil)

View Source

Same a get/3 but the value is interpreted like a duration format in Hocon.Period.

Example

iex> conf = Hocon.decode!(~s(a { b { c : "3 weeks" } }))
%{"a" => %{"b" => %{"c" => "30s"}}}
iex> Hocon.get_period(conf, "a.b.c")
%Hocon.Period{days: 21, months: 0, years: 0}
iex> Hocon.get_period(conf, "a.b.d")
nil
iex> Hocon.get_period(conf, "a.b.d", 7)
7
Link to this function

get_size(root, keypath, default \\ nil)

View Source

Same a get/3 but the value is interpreted like a number by using the power of 10.

Example

iex> conf = Hocon.decode!(~s(a { b { c : "10kb" } }))
%{"a" => %{"b" => %{"c" => "10kb"}}}
iex> Hocon.get_size(conf, "a.b.c")
10000
iex> Hocon.get_size(conf, "a.b.d")
nil
iex> Hocon.get_size(conf, "a.b.d", 1000)
1000