toml v0.5.2 Toml.Transform behaviour
Defines the behavior for custom transformations of decoded TOML values.
See the documentation for transform/2
for more details.
Link to this section Summary
Callbacks
This function is invoked for every key/value pair in the document, in a depth-first, bottom-up, traversal of the document
Link to this section Types
Link to this type
value()
value() :: %{optional(key()) => value()} | [value()] | number() | binary() | NaiveDateTime.t() | DateTime.t() | Date.t() | Time.t()
Link to this section Callbacks
This function is invoked for every key/value pair in the document, in a depth-first, bottom-up, traversal of the document.
The transformer must return one of two values:
{:error, term}
- an error occurred in the transformer, and decoding should failterm
- replace the value for the given key with the value returned from the transformer in the final document
Example
An example transformation would be the conversion of tables of a certain shape to a known struct value.
The struct:
defmodule Server do
defstruct [:name, :ip, :ports]
end
TOML which contains a table of this shape:
[servers.alpha]
ip = "192.168.1.1"
ports = [8080, 8081]
[servers.beta]
ip = "192.168.1.2"
ports = [8082, 8083]
And finally, the transforer implementation:
defmodule ServerTransform do
use Toml.Transform
# Transform IP strings to Erlang address tuples
def transform(:ip, ip) when is_binary(ip) do
case :inet.parse_ipv4_address(String.to_charlist(ip)) do
{:ok, result} ->
result
{:error, reason} ->
{:error, {:invalid_ip, ip, reason}}
end
end
# Non-binary values for IP addresses should return an error
def transform(:ip, ip), do: {:error, {:invalid_ip, ip, :expected_string}}
# Transform the server objects to Server structs
def transform(:servers, servers) when is_map(servers) do
for {name, server} <- servers do
struct(Server, Map.put(server, :name, name))
end
end
# Non-map values for servers should return an error
def transform(:servers, s), do: {:error, {:invalid_server, s}}
# Ignore all other values
def transform(_key, v), do: v
end
Assuming we decode with the following options:
Toml.decode!(content, keys: :atoms, transforms: [ServerTransform])
The result would be:
%{
servers: [
%Server{name: :alpha, ip: {192,168,1,1}, ports: [8080, 8081]},
%Server{name: :beta, ip: {192,168,1,2}, ports: [8082, 8083]}
]
}