Skip to content

Commit

Permalink
repo structural change and some added features
Browse files Browse the repository at this point in the history
  • Loading branch information
asdetrefle committed Apr 14, 2020
1 parent 07bb8e3 commit b5e1598
Show file tree
Hide file tree
Showing 19 changed files with 207 additions and 136 deletions.
21 changes: 10 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
cmake_minimum_required(VERSION 3.14.0)
project(toml VERSION 0.1)

### These flags should be removed eventually
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(tominal VERSION 0.1)

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
Expand All @@ -17,12 +12,12 @@ set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}")
option(TOML_BUILD_EXAMPLE "Build examples" OFF)
option(TOML_BUILD_TEST "Build tests" ON)

# Import tomlplusplus interface library
add_library(toml INTERFACE IMPORTED)
add_library(tominal INTERFACE IMPORTED)
set_target_properties(
toml PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}"
tominal PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/include"
)
target_compile_features(tominal INTERFACE cxx_std_17)

if(TOML_BUILD_TEST)
include(FetchContent)
Expand All @@ -35,5 +30,9 @@ if(TOML_BUILD_TEST)
FetchContent_MakeAvailable(googletest)

enable_testing()
add_subdirectory(test)
add_subdirectory(tests)
endif()

if(TOML_BUILD_EXAMPLE)
add_subdirectory(examples)
endif()
41 changes: 21 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,40 @@ C++ Alternatives:
To parse a TOML document from a file, you can do the following:

```cpp
#include "toml/toml.h"
#include "tominal/toml.h"

// ## Parsing
// `parse_file()` returns a `node_view` of a `toml::table`, which owns
// a copy of `std::shared_ptr<table>` so there is no lifetime issue.
// It will return an empty view if it catches an `toml::parse_error`.
auto config = cpptoml::parse_file("examples/example.toml").ok();
auto config = toml::parse_file("examples/example.toml").ok();

// ## Obtaining Basic Values
auto title = config["title"].value_or(""sv); // "TOML Example"sv
// or you want to have a `std::optional<std::string_view>`
auto optional_title = config["title"].value<std::string_view>().value();
auto title = config["title"].value_or("TOML"sv); // "TOML Example"sv
// or to have the default `std::string_view` if node_view is empty
auto default_title = config["title"].value_or_default<std::string_view>();

// ## Nested Tables
// Nested tables can be queried directly by chaining `[]` operator through
// the `node_view` and you can use a `map` function to convert to your data type
auto author = config["owner"]["name"].value_or(""sv); // "Tom Preston-Werner"
auto author = config["owner"]["name"].value_or("TOML");
auto enabled = config["database.enabled"].value_or_default<bool>();

// empty `std::optional<T>` will be mapped if node does not exist
auto dob = config["owner"]["dob"].map<offset_date_time>([](const auto &val) {
// map a node_view in place if it exists:
auto dob = config["owner.dob"].map<offset_date_time>([](const auto &val) {
return val.year * 10000 + val.month * 100 + val.day;
}); // std::optional{19790527}
});
config["owner.dob"].map<local_date>([](const auto &val) {}); // void callback


// ## Arrays of Values / Tables
// Similarly to `toml::table`, you can access the `node` of a table by `[]`
// operator. The are also `collect` and `map_collect` provided for convenience:
auto gamma = config["clients"][0]["data"][0][0].value_or(""sv);
auto data0 = config["clients"][0]["data"][0].collect<std::string_view>(); // std::vector{"gamma"sv, "delta"sv}

auto ports = config["database"]["ports"].map_collect<int>(
[](const auto &val) {
return val - 1;
}); // std::vector{8000, 8000, 8001}
auto gamma = config["clients"][0]["data"][1][1].value_or_default<int>();
auto data0 = config["clients"][1]["host"].collect<std::string_view>(); // std::vector{"omega"sv}
auto ports = config["database"]["ports"].map_collect<int>([](const auto &val) {
return val - 8000; // std::vector{0, 0, 1}
});
```

A problem I had with `cpptoml` was that I was not able to dereference an `rvalue` table or array:
Expand Down Expand Up @@ -97,12 +98,12 @@ Here are the fields of the date/time objects in cpptoml:
- minute\_offset (`offset_date_time`)


## Test Results - TODO
## Test Results

From [the toml-test suite][toml-test]:

```
126 passed, 0 failed // TODO with TOML v1.0.0-rc.1
116 passed, 12 failed // toml-test suite is only compliant with TOML v0.4.0
```

## Compilation
Expand All @@ -123,7 +124,7 @@ You can look at the files files `parse.cpp`, `parse_stdin.cpp`, and
`build_toml.cpp` in the root directory for some more examples.

`parse_stdin.cpp` shows how to use the visitor pattern to traverse an
entire `cpptoml::table` for serialization.
entire `toml::table` for serialization.

`build_toml.cpp` shows how to construct a TOML representation in-memory and
then serialize it to a stream.
Expand All @@ -136,4 +137,4 @@ then serialize it to a stream.
[toml11]: https://github.com/ToruNiina/toml11
[tinytoml]: https://github.com/mayah/tinytoml
[boost.toml]: https://github.com/ToruNiina/Boost.toml
[tomlplusplus]: https://github.com/marzer/tomlplusplus
[tomlplusplus]: https://github.com/marzer/tomlplusplus
25 changes: 14 additions & 11 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
### These flags should be removed eventually
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()

add_executable(parse parse.cpp)
target_link_libraries(parse cpptoml)
set_target_properties(parse PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED YES)
target_link_libraries(parse tominal)

add_executable(cpptoml-parser parse_stdin.cpp)
target_link_libraries(cpptoml-parser cpptoml)
set_target_properties(cpptoml-parser PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED YES)
add_executable(toml-parser parse_stdin.cpp)
target_link_libraries(toml-parser tominal)

if(FALSE)
add_executable(cpptoml-build build_toml.cpp)
target_link_libraries(cpptoml-build cpptoml)
set_target_properties(cpptoml-build PROPERTIES
Expand All @@ -25,3 +27,4 @@ set_target_properties(cpptoml-conversions PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED YES)
endif()
8 changes: 3 additions & 5 deletions examples/example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ enabled = true
ip = "10.0.0.2"
dc = "eqdc10"

[[clients]]
data = [ ["gamma", "delta"], [1, 2]]

[[clients]] # array of tables
data = [ ["gamma", "delta"], [1, 2]]

# Line breaks are OK when inside arrays
[[clients]]
hosts = [
{ name = "alpha" },
{ name = "alpha" }, # Line breaks are OK when inside arrays
"omega", # trailing comma and mixed type both allowd in array
]
14 changes: 6 additions & 8 deletions examples/parse.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "cpptoml.h"

#include <iostream>
#include <cassert>
#include "tominal/toml.h"

int main(int argc, char** argv)
{
Expand All @@ -11,14 +9,14 @@ int main(int argc, char** argv)
return 1;
}

try
if (auto result = toml::parse_file(argv[1]); result.is_ok())
{
std::shared_ptr<cpptoml::table> g = cpptoml::parse_file(argv[1]);
std::cout << (*g) << std::endl;
auto view = result.ok();
std::cout << view << std::endl;
}
catch (const cpptoml::parse_exception& e)
else
{
std::cerr << "Failed to parse " << argv[1] << ": " << e.what() << std::endl;
std::cerr << "Failed to parse " << argv[1] << ": " << result.err().what() << std::endl;
return 1;
}

Expand Down
47 changes: 16 additions & 31 deletions examples/parse_stdin.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "cpptoml.h"

#include <iostream>
#include <limits>
#include "tominal/toml.h"

/**
* A visitor for toml objects that writes to an output stream in the JSON
Expand All @@ -15,49 +14,49 @@ class toml_test_writer
// nothing
}

void visit(const cpptoml::value<std::string>& v)
void visit(const toml::value<std::string>& v)
{
stream_ << "{\"type\":\"string\",\"value\":\""
<< cpptoml::toml_writer::escape_string(v.get()) << "\"}";
<< toml::toml_writer::escape_string(v.get()) << "\"}";
}

void visit(const cpptoml::value<int64_t>& v)
void visit(const toml::value<int64_t>& v)
{
stream_ << "{\"type\":\"integer\",\"value\":\"" << v.get() << "\"}";
}

void visit(const cpptoml::value<double>& v)
void visit(const toml::value<double>& v)
{
stream_ << "{\"type\":\"float\",\"value\":\"" << v.get() << "\"}";
}

void visit(const cpptoml::value<cpptoml::local_date>& v)
void visit(const toml::value<toml::local_date>& v)
{
stream_ << "{\"type\":\"local_date\",\"value\":\"" << v.get() << "\"}";
}

void visit(const cpptoml::value<cpptoml::local_time>& v)
void visit(const toml::value<toml::local_time>& v)
{
stream_ << "{\"type\":\"local_time\",\"value\":\"" << v.get() << "\"}";
}

void visit(const cpptoml::value<cpptoml::local_datetime>& v)
void visit(const toml::value<toml::local_date_time>& v)
{
stream_ << "{\"type\":\"local_datetime\",\"value\":\"" << v.get()
<< "\"}";
}

void visit(const cpptoml::value<cpptoml::offset_datetime>& v)
void visit(const toml::value<toml::offset_date_time>& v)
{
stream_ << "{\"type\":\"datetime\",\"value\":\"" << v.get() << "\"}";
}

void visit(const cpptoml::value<bool>& v)
void visit(const toml::value<bool>& v)
{
stream_ << "{\"type\":\"bool\",\"value\":\"" << v << "\"}";
}

void visit(const cpptoml::array& arr)
void visit(const toml::array& arr)
{
stream_ << "{\"type\":\"array\",\"value\":[";
auto it = arr.get().begin();
Expand All @@ -70,27 +69,13 @@ class toml_test_writer
stream_ << "]}";
}

void visit(const cpptoml::table_array& tarr)
{
stream_ << "[";
auto arr = tarr.get();
auto ait = arr.begin();
while (ait != arr.end())
{
(*ait)->accept(*this);
if (++ait != arr.end())
stream_ << ", ";
}
stream_ << "]";
}

void visit(const cpptoml::table& t)
void visit(const toml::table& t)
{
stream_ << "{";
auto it = t.begin();
while (it != t.end())
{
stream_ << '"' << cpptoml::toml_writer::escape_string(it->first)
stream_ << '"' << toml::toml_writer::escape_string(it->first)
<< "\":";
it->second->accept(*this);
if (++it != t.end())
Expand All @@ -106,15 +91,15 @@ class toml_test_writer
int main()
{
std::cout.precision(std::numeric_limits<double>::max_digits10);
cpptoml::parser p{std::cin};
toml::parser p{std::cin};
try
{
std::shared_ptr<cpptoml::table> g = p.parse();
std::shared_ptr<toml::table> g = p.parse();
toml_test_writer writer{std::cout};
g->accept(writer);
std::cout << std::endl;
}
catch (const cpptoml::parse_exception& ex)
catch (const toml::parse_error& ex)
{
std::cerr << "Parsing failed: " << ex.what() << std::endl;
return 1;
Expand Down
2 changes: 2 additions & 0 deletions tominal/toml.h → include/tominal/toml.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
{
#define TOML_NAMESPACE_END }

#include <cstdint>

namespace toml
{
TOML_NAMESPACE_BEGIN
Expand Down
4 changes: 2 additions & 2 deletions tominal/toml_array.h → include/tominal/toml_array.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <vector>

#include "toml_base.h"
#include "toml_node.h"

Expand Down Expand Up @@ -178,7 +177,8 @@ class array final : public node
}

template <typename T, typename F, typename U = typename value_type_traits<T>::type,
typename V = std::invoke_result_t<F, const T &>>
typename V = std::invoke_result_t<F, const T &>,
typename = std::enable_if_t<!std::is_void_v<V>>>
std::vector<V> map_collect(F &&f) const
{
std::vector<V> result;
Expand Down
1 change: 1 addition & 0 deletions tominal/toml_base.h → include/tominal/toml_base.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
Expand Down
13 changes: 7 additions & 6 deletions tominal/toml_date_time.h → include/tominal/toml_date_time.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <iomanip>
#include "toml_base.h"

namespace toml
Expand Down Expand Up @@ -79,9 +80,9 @@ inline std::ostream &operator<<(std::ostream &os, const local_date &dt)
os.fill('0');

using std::setw;
os << setw(4) << static_cast<uint>(dt.year) << '-'
<< setw(2) << static_cast<uint>(dt.month) << '-'
<< setw(2) << static_cast<uint>(dt.day);
os << setw(4) << static_cast<uint16_t>(dt.year) << '-'
<< setw(2) << static_cast<uint16_t>(dt.month) << '-'
<< setw(2) << static_cast<uint16_t>(dt.day);

return os;
}
Expand All @@ -92,9 +93,9 @@ inline std::ostream &operator<<(std::ostream &os, const local_time &ltime)
os.fill('0');

using std::setw;
os << setw(2) << static_cast<uint>(ltime.hour) << ':'
<< setw(2) << static_cast<uint>(ltime.minute) << ':'
<< setw(2) << static_cast<uint>(ltime.second);
os << setw(2) << static_cast<uint16_t>(ltime.hour) << ':'
<< setw(2) << static_cast<uint16_t>(ltime.minute) << ':'
<< setw(2) << static_cast<uint16_t>(ltime.second);

if (ltime.nanosecond > 0)
{
Expand Down
Loading

0 comments on commit b5e1598

Please sign in to comment.