Skip to content

Commit

Permalink
- The formatting options that were passed as a parameter to `toml.enc…
Browse files Browse the repository at this point in the history
…ode`, `toml.encodeToFile`, `toml.toJSON`, and `toml.toYAML` previously had no effect when overriding values.

- Resolved CMake `FetchContent_Populate` warning.
- Updated to magic_enum v0.9.7.
- Added encoding options tests.
  • Loading branch information
LebJe committed Nov 19, 2024
1 parent 44a4056 commit ffc000e
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 30 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.1](https://github.com/LebJe/toml.lua/releases/tag/0.4.1) - 2024-11-19

### Fixed
- The formatting options that were passed as a parameter to `toml.encode`, `toml.encodeToFile`, `toml.toJSON`, and `toml.toYAML` previously had no effect when overriding values.
- Resolved CMake `FetchContent_Populate` warning.

### Changed
- Updated to magic_enum v0.9.7.

### Added
- Added tests for encoding options.

## [0.4.0](https://github.com/LebJe/toml.lua/releases/tag/0.4.0) - 2024-01-02

### Added
Expand Down
5 changes: 1 addition & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,24 @@ FetchContent_Declare(
GIT_REPOSITORY "https://github.com/Neargye/magic_enum.git"
GIT_SHALLOW ON
GIT_SUBMODULES ""
GIT_TAG "v0.9.5"
GIT_TAG "v0.9.7"
)

FetchContent_GetProperties(${TOML++})
if(NOT ${TOML++}_POPULATED)
message(STATUS "Cloning ${TOML++}")
#FetchContent_Populate(${TOML++})
FetchContent_MakeAvailable(${TOML++})
endif()

FetchContent_GetProperties(${SOL2})
if(NOT ${SOL2}_POPULATED)
message(STATUS "Cloning ${SOL2}")
FetchContent_Populate(${SOL2})
FetchContent_MakeAvailable(${SOL2})
endif()

FetchContent_GetProperties(${MAGIC_ENUM})
if(NOT ${MAGIC_ENUM}_POPULATED)
message(STATUS "Cloning ${MAGIC_ENUM}")
FetchContent_Populate(${MAGIC_ENUM})
FetchContent_MakeAvailable(${MAGIC_ENUM})
endif()

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ 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.
`toml.encode`, `toml.encodeToFile`, `toml.toJSON`, and `toml.toYAML` all take an optional second (third in the case of `toml.encodeToFile`) 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.

```lua
Expand Down Expand Up @@ -514,10 +514,10 @@ Passing an empty table removes all options, while not providing a table will use
allowHexadecimalIntegers = true,

--- Apply indentation to tables nested within other tables/arrays.
indentSubTables = true,
indentSubTables = false,

--- Apply indentation to array elements when the array is forced to wrap over multiple lines.
indentArrayElements = true,
indentArrayElements = false,

--- Combination of `indentSubTables` and `indentArrayElements`.
indentation = true,
Expand Down
77 changes: 59 additions & 18 deletions src/utilities/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ static std::map<format_flags, bool> defaultFlags =
{ format_flags::allow_hexadecimal_integers, true },
{ format_flags::allow_octal_integers, true },
{ format_flags::indent_sub_tables, false },
{ format_flags::indent_array_elements, false },
{ format_flags::indentation, true },
{ format_flags::relaxed_float_precision, false },
{ format_flags::terse_key_value_pairs, false } };
Expand Down Expand Up @@ -92,19 +93,28 @@ inline toml::format_flags defaultFormatFlags() {
return flags;
}

void addFlag(toml::format_flags & flags, sol::table & flagsTable, toml::format_flags flagToAdd) {
auto tableFlag = flagsTable[camelCase(magic_enum::enum_name(flagToAdd))];

if (tableFlag.valid()) {
flags |= tableFlag.get<bool>() ? flagToAdd : flags;
} else {
// Use default
flags |= defaultFlags[flagToAdd] ? flagToAdd : flags;
};
}
// void addFlag(toml::format_flags & flags, sol::table & flagsTable, toml::format_flags flagToAdd) {
// auto tableFlag = flagsTable[camelCase(magic_enum::enum_name(flagToAdd))];

// std::cout << "addFlag: \nenum_name: " << magic_enum::enum_name(flagToAdd) << "\n";

// std::cout << "camel case name: " << camelCase(magic_enum::enum_name(flagToAdd)) << "\n";

// if (tableFlag.valid()) {
// std::cout << "Is valid: " << camelCase(magic_enum::enum_name(flagToAdd)) << "\n";
// if (tableFlag.get<bool>()) {
// flags |= flagToAdd;
// }
// } else {
// // Use default
// if (defaultFlags[flagToAdd]) {
// flags |= flagToAdd;
// }
// };
// }

toml::format_flags tableToFormatFlags(sol::optional<sol::table> t) {
auto flags = format_flags();
auto flags = format_flags::none;

// Set default flags.
if (!t) {
Expand All @@ -116,14 +126,45 @@ toml::format_flags tableToFormatFlags(sol::optional<sol::table> t) {

// User passed an empty table to clear all flags.
if (table.empty()) return flags;

constexpr auto f = magic_enum::enum_values<format_flags>();
for (auto flag : f) {
addFlag(flags, table, flag);

// Set default flags, and allow user to override
//flags = defaultFormatFlags();

// Set default flags, and allow user to override
std::map<format_flags, bool> userFlags = defaultFlags;

for (auto [flag, enabled] : userFlags) {
std::string camelCaseFlagName = camelCase(magic_enum::enum_name(flag));
if (table[camelCaseFlagName].valid()) {
userFlags[flag] = table[camelCaseFlagName].get<bool>();
}
}

// `format_flags::indentation` is not returned from `enum_values`.
addFlag(flags, table, format_flags::indentation);

// `format_flags::indentation` is returned as an empty string from `magic_enum::enum_name`, so we must handle it separately.
if (table["indentation"].valid()) {
userFlags[toml::format_flags::indentation] = table["indentation"].get<bool>();
}

std::cout << "UserFlags:\n";

for (auto [flag, enabled] : userFlags) {
std::cout << "Flag: " << magic_enum::enum_name(flag) << ", Enabled: " << (enabled ? "True" : "False") << "\n";
}

for (auto [flag, enabled] : userFlags) {
if (enabled) flags |= flag;
}

// constexpr auto f = magic_enum::enum_values<format_flags>();
// for (auto flag : f) {
// addFlag(flags, table, flag);
// }

// // `format_flags::indentation` is not returned from `enum_values`, so we must handle it separately.
// if (table["indentation"].valid()) {
// flags |= toml::format_flags::indentation;
// }

return flags;
}

Expand Down
10 changes: 8 additions & 2 deletions src/utilities/utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

/// Converts a string into [Camel Case](https://en.wikipedia.org/wiki/Camel_case).
///
/// The code in this function is based on https://en.wikipedia.org/wiki/Camel_case
/// The code in this function is based on https://codereview.stackexchange.com/a/263761
std::string camelCase(std::string s) noexcept;

/// Version of `camelCase` that accepts a `string_view`.
Expand All @@ -36,7 +36,8 @@ std::string parseErrorToString(toml::parse_error e);
/// Inserts the values in `e` into `table`.
void parseErrorToTable(toml::parse_error e, sol::table & table);

/// Takes a Lua table, with keys representing flag names, and values
/// Takes a Lua table, with keys representing flag names, and values, and converts it to `toml::format_flags`.
/// If the table is nil, all format flags are set to their default value, if the table is empty, `toml::format_flags` is set to none.
toml::format_flags tableToFormatFlags(sol::optional<sol::table> t);

Options tableToOptions(sol::optional<sol::table> t);
Expand All @@ -55,4 +56,9 @@ std::optional<std::string> keyToString(sol::object key);
/// If a string is not on the stack, then an integer from `luaL_argerror` is returned.
std::variant<int, toml::table *> getTableFromStringInState(sol::state_view state, int index = 1);

template <>
struct magic_enum::customize::enum_range<toml::format_flags> {
static constexpr bool is_flags = true;
};

#endif /* UTILITIES_H */
38 changes: 38 additions & 0 deletions tests/test-data/encoding/noIndentation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"database" : {
"data" : [
[
"delta",
"phi"
],
[
3.1400000000000001
]
],
"enabled" : true,
"ports" : [
8000,
8001,
8002
],
"temp_targets" : {
"case" : 72,
"cpu" : 79.5
}
},
"owner" : {
"dob" : "1979-05-27T07:32:00-08:00",
"name" : "Tom Preston-Werner"
},
"servers" : {
"alpha" : {
"ip" : "10.0.0.1",
"role" : "frontend"
},
"beta" : {
"ip" : "10.0.0.2",
"role" : "backend"
}
},
"title" : "TOML Example"
}
22 changes: 22 additions & 0 deletions tests/test-data/encoding/terseKeys+qoutedTimestamps.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
title="TOML Example"

[database]
data=[ [ "delta", "phi" ], [ 3.1400000000000001 ] ]
enabled=true
ports=[ 8000, 8001, 8002 ]

[database.temp_targets]
case=72
cpu=79.5

[owner]
dob="1979-05-27T07:32:00-08:00"
name="Tom Preston-Werner"

[servers.alpha]
ip="10.0.0.1"
role="frontend"

[servers.beta]
ip="10.0.0.2"
role="backend"
13 changes: 12 additions & 1 deletion tests/tests.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
lu = require("luaunit")
local lu = require("luaunit")
local toml = require("toml")
local data = require("tests/tables")

Expand Down Expand Up @@ -29,6 +29,17 @@ function TestEncoder:testEncodeMassiveTable()
lu.assertEquals(toml.encode(data.tableForMassiveToml), massive)
end

function TestEncoder:testEncodingOptions()
local terseKeysToml = read("tests/test-data/encoding/terseKeys+qoutedTimestamps.toml")

lu.assertEquals(toml.encode(toml.decode(terseKeysToml), { terseKeyValuePairs = true, quoteDatesAndTimes = true }), terseKeysToml)

local noIndentationJSON = read("tests/test-data/encoding/noIndentation.json")

lu.assertEquals(toml.toJSON(toml.decode(terseKeysToml), { indentation = false }), noIndentationJSON)

end

function TestDecoder:testDecodeSamples()
lu.assertEquals(data.tableForTestConfigToml, toml.decodeFromFile("tests/test-data/testConfig.toml"))
lu.assertEquals(data.tableForTestConfig2Toml, toml.decodeFromFile("tests/test-data/testConfig2.toml"))
Expand Down
2 changes: 1 addition & 1 deletion toml-0.4.0-0.rockspec → toml-0.4.1-0.rockspec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package = "toml"
version = "0.4.0-0"
version = "0.4.1-0"

local v = version:gsub("%-%d", "")

Expand Down
2 changes: 1 addition & 1 deletion toml.d.tl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ local record toml

--- Encodes a Lua table into a TOML document, and **appends** that document to a file.
--- @param data table: The Lua table to be encoded.
--- @param file string: The file to write the document to/
--- @param file string: The file to write the document to.
--- @param options FormattingOptions|nil: Options for formatting the YAML document. Pass `{}` to remove all options, or no table to use the default options.
encodeToFile: function(data: { string: any }, fileOrOptions: string|EncodeToFileOptions, options: FormattingOptions|nil)

Expand Down

0 comments on commit ffc000e

Please sign in to comment.