Giter Site home page Giter Site logo

lebje / toml.lua Goto Github PK

View Code? Open in Web Editor NEW
33.0 1.0 0.0 585 KB

TOML v1.0.0 parser and serializer for Lua. Powered by toml++.

License: MIT License

CMake 10.98% C++ 43.10% Lua 41.18% Ruby 0.08% Shell 0.86% PowerShell 2.46% Batchfile 1.34%
lua lua53 toml toml-parser toml-serializer parser serializer lua54 luajit tomlplusplus

toml.lua's Introduction

toml.lua

TOML v1.0.0 parser and serializer for Lua. Powered by toml++.

Build and Test on MacOS Build and Test on Linux Build and Test on Windows LuaRocks

toml.lua is a Lua wrapper around toml++, allowing you to parse and serialize TOML in Lua.

Table of Contents

Created by gh-md-toc

Installation

Requirements

  • A C++ 17 compiler (Clang, GCC, MinGW)
  • CMake
  • Lua C headers (lua.h, lualib.h, and lauxlib.h)
  • Lua library (e.g. liblua51.<so|dylib|dll>)
  • Lua >= 5.1 or LuaJIT

LuaRocks

MacOS and Linux

luarocks install toml

Windows

LLVM

If you have installed Clang (https://llvm.org), and CMake is configured to use it, you can run:

luarocks install toml
MinGW

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

Manual Compilation

MacOS and Linux

  1. 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 the include and lib folders for your Lua installation. For example: LUA_DIR=/usr/local/openresty/luajit cmake -S . -B build -G <generator-name>

  1. Run cmake --build build --config Release to build the project.
  2. You will find the toml.so dynamic library in the build folder.

Tip: use cmake --help to see a list of available generator names.

The above is based off of xpol/lua-rapidjson's README.

Windows

If LuaJIT is not installed, or your installation does not have the Lua headers, go to install LuaJIT.

Build with MinGW

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.

Build with LLVM

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.

Install LuaJIT

If you don't have LuaJIT, or your installation does not have the Lua headers, you can:

  1. Install MinGW (choco install mingw)

  2. Run scripts\buildLuaJIT.ps1:

powershell scripts\buildLuaJIT.ps1 -installDir "LuaJIT"

to build and install LuaJIT.

Usage

Decoding

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
	}
}
--]]

Decoding Options

temporalTypesAsUserData
  • temporalTypesAsUserData = true: The userdata types toml.Date, toml.Time, and toml.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
  • formattedIntsAsUserData = true: The userdata type toml.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,
}
--]]

Encoding

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
--]]

Error Handling

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

Inline Tables

Use setmetatable(myTable, { inline = true }) to create an inline table.

TOML Conversion

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
]]

JSON

-- Convert from a string
local json = toml.toJSON(tomlStr)

-- or from a table
json = toml.toJSON(toml.decode(tomlStr))

print(json)

YAML

local yaml = toml.toYAML(tomlStr)
yaml = toml.toYAML(toml.decode(tomlStr))
print(yaml)

Output Formatting

Formatting Integers

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
--]]

Formatting TOML, JSON, or YAML

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
}

Date and Time

(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

Dependencies

Licenses

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.

Contributing

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.

toml.lua's People

Contributors

github-actions[bot] avatar lebje avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

toml.lua's Issues

"temporalTypesAsUserData = false" option has no effect?

I have been trying to use this option in my code with no effect to emitted output. Finally, I just copied and pasted the example shown in the README.md file, and again there seems to be no difference in emitted output by inspect.

If I select an individual (date) item to simply print then the output is the string equivalent of the date.

Am I missing something or is the temporalTypesAsUserData a NOOP?

advTHANKSance

Boolean values get decoded as integers rather than as booleans

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 succeeded, decoded_toml = pcall(toml.decode, tomlStr)

assert(decoded_toml.c == 1) -- succeeds (but shouldn't)
assert(decoded_toml.c == true) -- fails (but should succeed)

Install log:

❯ luarocks install toml
Installing https://luarocks.org/toml-0.1.1-0.src.rock

toml 0.1.1-0 depends on lua >= 5.1 (5.4-1 provided by VM)
Warning: unmatched variable LINK_FLAGS
Warning: unmatched variable LUA_LIBRARIES
-- The C compiler identification is AppleClang 13.1.6.13160021
-- The CXX compiler identification is AppleClang 13.1.6.13160021
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Cloning toml++
-- Cloning sol2
-- Cloning magic_enum
-- Performing Test COMPILER_SUPPORTS_ARCH_NATIVE
-- Performing Test COMPILER_SUPPORTS_ARCH_NATIVE - Failed
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/sam/.tmp/luarocks_toml-0.1.1-0-4410119/toml.lua/build.luarocks
[ 16%] Building CXX object CMakeFiles/toml.lua.dir/src/toml.cpp.o
[ 33%] Building CXX object CMakeFiles/toml.lua.dir/src/decoding/decoding.cpp.o
[ 50%] Building CXX object CMakeFiles/toml.lua.dir/src/encoding/encoding.cpp.o
[ 66%] Building CXX object CMakeFiles/toml.lua.dir/src/DateAndTime/dateAndTime.cpp.o
[ 83%] Building CXX object CMakeFiles/toml.lua.dir/src/utilities/utilities.cpp.o
[100%] Linking CXX shared module toml.so
[100%] Built target toml.lua
[100%] Built target toml.lua
Install the project...
-- Install configuration: "Release"
-- Installing: /opt/homebrew/lib/luarocks/rocks-5.4/toml/0.1.1-0/lib/toml.so
toml 0.1.1-0 is now installed in /opt/homebrew (license: MIT)

Lua 5.4, macOS 12.4, using via Hammerspoon.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.