toml_bombadil

A wrapper for the Erlang tomerl library


Keywords
erlang, hacktoberfest, lfe, maps, toml
License
Apache-2.0

Documentation

bombadil

A wrapper for the Erlang toml library that uses the map data structure

Build Status LFE Versions Erlang Versions Tag

Project Logo

Table of Contents

About

This is an LFE TOML library 100% usable in any other BEAM language that is capable of building rebar3-based projects. It does a couple of useful and convenient things:

  1. Provides a read function that recursively converts all of the toml Erlang dicts to maps and converts the toml library's type tuples to just the values themselves.
  2. Provides Clojure-inspired functions for accessing and updating map data (assoc, assoc-in, get-in). Note however that, due to the fact that Erlang and LFE, unlike Clojure, do not support arbitrary arity in function definitions, the signature and use of some of these functions is different than the similar ones in Clojure.
  3. Provides a set of functions in the bombadil module which just call the same functions in the toml library. Note that these aliases have been Lispified (underscores to dashes); for Erlangers we've supplied aliases with underscores.
  4. Lastly, makes public the utility functions used for the conversion from toml dicts to bombadil maps, in the event that these are useful for your own project (or debugging).

Build

$ rebar3 compile

Start the Project REPL

$ rebar3 repl

or for Erlang:

$ rebar3 shell

Tests

$ rebar3 ltest

Usage

Read a TOML file, parse its contents, and convert the parsed data to an Erlang map:

(set data (bombadil:read "priv/testing/deep-sections.toml"))

or from Erlang:

1> Data = bombadil:read("priv/testing/deep-sections.toml").

One may work with the resulting data structure in the following ways:

lfe> (bombadil:get data "ab")
42
lfe> (bombadil:get-in data '("a" "b" "d" "e"))
#M("in" "deep")
lfe> (bombadil:assoc-in data '("a" "b" "d" "e") 42)
#M("ab" 42
   "cd" 3.14159
   "a" #M("stuff" "things"
          "b" #M("other" "stuff"
                 "c" #M("things" "n stuff")
                 "d" #M("things" "n other things"
                        "e" 42))
        "f" #M("other" "things"))
   "g" #M("h" #M("woah" "wut"))
   "i" #M("j" #M("k" #M("no" "way")))
   "l" #M("stuff" "fur reelies"))

or from Erlang:

2> bombadil:get(Data, "ab").
42
3> bombadil:get_in(Data, ["a", "b", "d", "e"]).
#{"in" => "deep"}
4> bombadil:assoc_in(Data, ["a", "b", "d", "e"], 42).
#{"ab" => 42,
  "cd" => 3.14159,
  "a" => #{"stuff" => "things"
           "b" => #{"other" => "stuff"
                    "c" => #{"things" => "n stuff"},
                    "d" => #{"things" => "n other things"
                             "e" => 42,}},
           "f" => #{"other" => "things"}},
  "g" => #{"h" => #{"woah" => "wut"}},
  "i" => #{"j" => #{"k" => #{"no" => "way"}}},
  "l" => #{"stuff" => "fur reelies"}}

Note that since all of these functions have data as their first argument, the "thread-left" macro in LFE -- -> -- may be used to chain outputs:

lfe> (include-lib "lfe/include/clj.lfe")
lfe> (-> data
         (bombadil:assoc-in '("a" "b" "d" "e") 42)
         (bombadil:get-in '("a" "b" "d" "e")))
42

This is, of course, a contrived example; those who have used the data threading macros in the past are well familiar with the benefits (mostly in code clarity and thus ease of debugging and maintenance).

Unfortunately this LFE macro convenience is not usable from Erlang.

License

Apache License, Version 2.0

Copyright © 2020, Duncan McGreggor oubiwann@gmail.com.