TOML v1.0.0 parser and serializer for Lua. Powered by toml++.
toml.lua is a Lua wrapper around toml++, allowing you to parse and serialize TOML in Lua.
Created by gh-md-toc
- A C++ 17 compiler (Clang, GCC, MinGW)
- CMake
- Lua C headers (
lua.h
,lualib.h
, andlauxlib.h
) - Lua library (e.g.
liblua51.<so|dylib|dll>
) - Lua >= 5.1 or LuaJIT
luarocks install toml
If you have installed Clang (https://llvm.org), and CMake is configured to use it, you can run:
luarocks install toml
If you have installed MinGW, and CMake is configured to use it, you can run:
luarocks config variables.LINK_FLAGS "path\to\LuaJIT\bin\lua51.dll"
luarocks install toml
luarocks config variables.LINK_FLAGS --unset
- Run
cmake -S . -B build -G <generator-name>
to generate the required files.
If you have a non standard Lua install location, add the environment variable
LUA_DIR
and have it point to the directory containing theinclude
andlib
folders for your Lua installation. For example:LUA_DIR=/usr/local/openresty/luajit cmake -S . -B build -G <generator-name>
- Run
cmake --build build --config Release
to build the project. - You will find the
toml.so
dynamic library in thebuild
folder.
Tip: use
cmake --help
to see a list of available generator names.
The above is based off of xpol/lua-rapidjson's README.
If LuaJIT is not installed, or your installation does not have the Lua headers, go to install LuaJIT.
Install MinGW (choco install mingw
), then:
cmake.exe -S . -B build -G "MinGW Makefiles" -DLUA_INCLUDE_DIR="path\to\LuaJIT\include" -DLINK_FLAGS="path\to\LuaJIT\bin\lua51.dll"
cmake.exe --build build --config Release
You'll find the toml.dll
file in the build
directory.
Install LLVM and Ninja (choco install llvm ninja
), then:
cmake.exe -S . -B build -G "Ninja Multi-Config" -DLUA_INCLUDE_DIR="path\to\LuaJIT\include"
cmake.exe --build build --config Release
You'll find the toml.dll
file in the build
directory.
If you don't have LuaJIT, or your installation does not have the Lua headers, you can:
-
Install MinGW (
choco install mingw
) -
Run
scripts\buildLuaJIT.ps1
:
powershell scripts\buildLuaJIT.ps1 -installDir "LuaJIT"
to build and install LuaJIT.
local tomlStr = [[
a = 1275892
b = 'Hello, World!'
c = true
d = 124.2548
[e]
f = [ 1, 2, 3, '4', 5.142 ]
g = 1979-05-27
h = 07:32:00
i = 1979-05-27T07:32:00-07:00
]]
local toml = require("toml")
local inspect = require("inspect")
-- Decode from string
local succeeded, table = pcall(toml.decode, tomlStr)
-- Decode from file
succeeded, table = pcall(toml.decodeFromFile, "configuration.toml")
if succeeded then
-- Use `table`.
print(inspect(table))
else
-- Error details are in `table`.
end
--[[
{
a = 1275892,
b = "Hello, World!",
c = true,
d = 124.2548,
e = {
f = { 1, 2, 3, "4", 5.142 },
g = <userdata 1> -- 1979-05-27,
h = <userdata 2> -- 07:32:00,
i = <userdata 3> -- 1979-05-27T07:32:00-07:00
}
}
--]]
-
temporalTypesAsUserData = true
: The userdata typestoml.Date
,toml.Time
, andtoml.DateTime
are used to represent TOML date and time types. -
temporalTypesAsUserData = false
: Lua tables are used to represent TOML date and time types.
The default value is
true
formattedIntsAsUserData = true
: The userdata typetoml.Int
is used to represent integers in octal, binary, or hexadecimal format.formattedIntsAsUserData = false
: Integers in octal, binary, or hexadecimal format will be represented in decimal.
The default value is
false
local tomlStr = [[
date = 1979-05-27
time = 07:32:00
datetime = 1979-05-27T07:32:00-07:00
hexadecimal = 0x16C3
binary = 0b110110011011
octal = 0x169F
]]
local table1 = toml.decode(tomlStr, { temporalTypesAsUserData = true, formattedIntsAsUserData = true })
local table2 = toml.decode(tomlStr, { temporalTypesAsUserData = false, formattedIntsAsUserData = false })
print(inspect(table1))
--[[
{
date = <userdata 1> -- 1979-05-27, <-- toml.Date
time = <userdata 2> -- 07:32:00 <-- toml.Time
datetime = <userdata 3> -- 1979-05-27T07:32:00-07:00, <-- toml.DateTime
binary = <userdata 4> -- 0b10011011, <-- toml.Int (with `toml.formatting.int.binary` flag)
hexadecimal = <userdata 5> -- 0x16c3, <-- toml.Int (with `toml.formatting.int.octal` flag)
octal = <userdata 6> -- 0x169f, <-- toml.Int (with `toml.formatting.int.hexadecimal` flag)
}
--]]
print(inspect(table2))
--[[
{
date = {
day = 27,
month = 5,
year = 1979
},
time = {
hour = 7,
minute = 32,
nanoSecond = 0,
second = 0
},
datetime = {
date = {
day = 27,
month = 5,
year = 1979
},
time = {
hour = 7,
minute = 32,
nanoSecond = 0,
second = 0
},
timeOffset = {
minutes = -420
}
},
binary = 3483,
hexadecimal = 5827,
octal = 5791,
}
--]]
local toml = require("toml")
-- Inline tables: https://toml.io/en/v1.0.0#inline-table
local inlineTable = {
a = 1275892,
b = "Hello, World!",
c = true,
d = 124.2548,
}
-- Make the table inline.
setmetatable(inlineTable, { inline = true })
local table = {
e = {
f = { 1, 2, 3, "4", 5.142 },
g = toml.Date.new(1979, 05, 27),
-- year month day
h = toml.Time.new( 7, 32, 0, 0),
-- hour minute second nanoSecond
i = toml.DateTime.new(
toml.Date.new(1979, 05, 27),
toml.Time.new(7, 32, 0, 0),
toml.TimeOffset.new( -7, 0)
-- hour minute
)
},
inlineTable = inlineTable
}
-- Encode to string
local succeeded, documentOrErrorMessage = pcall(toml.encode, table)
-- Encode to file, this will **append** to the file.
succeeded, documentOrErrorMessage = pcall(toml.encodeToFile, table, "configuration.toml")
-- Encode to file, this will **overwrite** the file.
succeeded, documentOrErrorMessage = pcall(toml.encodeToFile, table, { file = "configuration.toml", overwrite = true })
if succeeded then
-- Successfully encoded to string / wrote to file
print(tomlDocumentOrErrorMessage)
else
-- Error occurred
print(tomlDocumentOrErrorMessage)
end
--[[
inlineTable = { a = 1275892, b = "Hello, World!", c = true, d = 124.2548 }
[e]
f = [ 1, 2, 3, "4", 5.1420000000000003 ]
g = 1979-05-27
h = 07:32:00
i = 1979-05-27T07:32:00-07:00
--]]
local tomlStr = [[
a = 1275892
b = 'Hello, World!'
c = true
d = 124. # <-- ERROR: "Expected decimal digit"
[e]
f = [ 1, 2, 3, '4', 5.142 ]
g = 1979-05-27
h = 07:32:00
i = 1979-05-27T07:32:00-07:00
]]
local toml = require("toml")
local inspect = require("inspect")
local succeeded, table = pcall(toml.decode, tomlStr)
if succeeded then
-- Use decoded table.
print(inspect(table))
else
-- Error details are in `table`.
print(inspect(table))
--[[
{
begin = {
column = 9,
line = 4
},
end = {
column = 9,
line = 4
},
reason = "Error while parsing floating-point: expected decimal digit, saw '\\n'"
}
--]]
end
Use setmetatable(myTable, { inline = true })
to create an inline table.
local toml = require("toml")
local tomlStr = [[
a = 1275892
b = 'Hello, World!'
c = true
d = 124.2548
[e]
f = [ 1, 2, 3, '4', 5.142 ]
g = 1979-05-27
h = 07:32:00
i = 1979-05-27T07:32:00-07:00
]]
-- Convert from a string
local json = toml.toJSON(tomlStr)
-- or from a table
json = toml.toJSON(toml.decode(tomlStr))
print(json)
local yaml = toml.toYAML(tomlStr)
yaml = toml.toYAML(toml.decode(tomlStr))
print(yaml)
local toml = require("toml")
local normalIntegers = {
int1 = 2582
int2 = 3483
int3 = 5971
}
print(toml.encode(normalIntegers))
--[[
int1 = 2582
int2 = 3483
int3 = 5791
--]]
local formattedIntegers = {
int1 = toml.Int.new(2582, toml.formatting.int.octal),
int2 = toml.Int.new(3483, toml.formatting.int.binary),
int3 = toml.Int.new(5791, toml.formatting.int.hexadecimal)
}
print(toml.encode(formattedIntegers))
--[[
int1 = 0o5026
int2 = 0b110110011011
int3 = 0x169F
--]]
-- Use `int` and `flags` properties to assign and retrieve flags and integers.
local int = formattedIntegers.int1.int
local flags = formattedIntegers.int1.flags
formattedIntegers.int1.int = 5827
formattedIntegers.int1.flags = toml.formatting.int.hexadecimal
print(toml.encode(formattedIntegers))
--[[
int1 = 0x16C3
int2 = 0b110110011011
int3 = 0x169F
--]]
toml.encode
, toml.encodeToFile
, toml.toJSON
, and toml.toYAML
all take an optional second parameter: a table containing keys that disable or enable different formatting options.
Passing an empty table removes all options, while not providing a table will use the default options.
{
--- Dates and times will be emitted as quoted strings.
quoteDatesAndTimes = false,
--- Infinities and NaNs will be emitted as quoted strings.
quoteInfinitesAndNaNs = false,
--- Strings will be emitted as single-quoted literal strings where possible.
allowLiteralStrings = false,
--- Strings containing newlines will be emitted as triple-quoted 'multi-line' strings where possible.
allowMultiLineStrings = false,
--- Allow real tab characters in string literals (as opposed to the escaped form `\t`).
allowRealTabsInStrings = false,
--- Allow non-ASCII characters in strings (as opposed to their escaped form, e.g. `\u00DA`).
allow_unicode_strings = true,
--- Allow integers with `toml.formatting.int.binary` to be emitted as binary.
allowBinaryIntegers = true,
--- Allow integers with `toml.formatting.int.octal` to be emitted as octal.
allowOctalIntegers = true,
--- Allow integers with `toml.formatting.int.hexadecimal` to be emitted as hexadecimal.
allowHexadecimalIntegers = true,
--- Apply indentation to tables nested within other tables/arrays.
indentSubTables = true,
--- Apply indentation to array elements when the array is forced to wrap over multiple lines.
indentArrayElements = true,
--- Combination of `indentSubTables` and `indentArrayElements`.
indentation = true,
--- Emit floating-point values with relaxed (human-friendly) precision.
---
--- Warning: Setting this flag may cause serialized documents to no longer round-
--- trip correctly since floats might have a less precise value upon being written out
--- than they did when being read in. Use this flag at your own risk.
relaxedFloatPrecision = false,
--- Avoids the use of whitespace around key-value pairs.
terseKeyValuePairs = false
}
(Creating Date, Time, and DateTime is shown in the encoding section)
record Date
year: number
month: number
day: number
new: function(year: number, month: number, day: number): Date
end
record Time
hour: number
minute: number
second: number
nanoSecond: number
new: function (
hour: number,
minute: number,
second: number,
nanoSecond: number
): Time
end
record TimeOffset
minutes: number
new: function (hours: number, minutes: number): TimeOffset
end
record DateTime
date: Date
time: Time
TimeOffset: nil | TimeOffset
new: function(date: Date, time: Time): DateTime
new: function(date: Date, time: Time, timeOffset: TimeOffset): DateTime
end
The comments for the options are from the tomlplusplus documentation
The toml++ license is available at https://github.com/marzer/tomlplusplus/blob/master/LICENSE.
The sol2 license is available at https://github.com/ThePhD/sol2/blob/develop/LICENSE.txt.
The magic_enum license is available at https://github.com/Neargye/magic_enum/blob/master/LICENSE.
Before committing, please install pre-commit, clang-format, StyLua, and Prettier, then install the pre-commit hooks. On MacOS, it would look like:
$ brew bundle # install the packages specified in Brewfile
$ pre-commit install
# Commit your changes.
To install pre-commit on other platforms, refer to the documentation.