mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 17:58:09 +08:00
Merge pull request #46 from ToruNiina/toml-literal
feat: add ""_toml literal
This commit is contained in:
@@ -20,6 +20,7 @@ set(TEST_NAMES
|
||||
test_parse_inline_table
|
||||
test_parse_key
|
||||
test_parse_table_key
|
||||
test_literals
|
||||
test_get
|
||||
test_get_related_func
|
||||
test_from_toml
|
||||
|
129
tests/test_literals.cpp
Normal file
129
tests/test_literals.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#define BOOST_TEST_MODULE "test_literals"
|
||||
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#else
|
||||
#define BOOST_TEST_NO_LIB
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
#endif
|
||||
#include <toml.hpp>
|
||||
#include <map>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_file_as_literal)
|
||||
{
|
||||
using namespace toml::literals::toml_literals;
|
||||
|
||||
{
|
||||
const toml::value r{{"a", 42}, {"b", "baz"}};
|
||||
const toml::value v = u8R"(
|
||||
a = 42
|
||||
b = "baz"
|
||||
)"_toml;
|
||||
|
||||
BOOST_CHECK_EQUAL(r, v);
|
||||
}
|
||||
{
|
||||
const toml::value r{
|
||||
{"c", 3.14},
|
||||
{"table", toml::table{{"a", 42}, {"b", "baz"}}}
|
||||
};
|
||||
const toml::value v = u8R"(
|
||||
c = 3.14
|
||||
[table]
|
||||
a = 42
|
||||
b = "baz"
|
||||
)"_toml;
|
||||
|
||||
BOOST_CHECK_EQUAL(r, v);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_value_as_literal)
|
||||
{
|
||||
using namespace toml::literals::toml_literals;
|
||||
|
||||
{
|
||||
const toml::value v1 = u8"true"_toml;
|
||||
const toml::value v2 = u8"false"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_boolean());
|
||||
BOOST_CHECK(v2.is_boolean());
|
||||
BOOST_CHECK(toml::get<bool>(v1));
|
||||
BOOST_CHECK(!toml::get<bool>(v2));
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8"123_456"_toml;
|
||||
const toml::value v2 = u8"0b0010"_toml;
|
||||
const toml::value v3 = u8"0xDEADBEEF"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_integer());
|
||||
BOOST_CHECK(v2.is_integer());
|
||||
BOOST_CHECK(v3.is_integer());
|
||||
BOOST_CHECK_EQUAL(toml::get<toml::integer>(v1), 123456);
|
||||
BOOST_CHECK_EQUAL(toml::get<toml::integer>(v2), 2);
|
||||
BOOST_CHECK_EQUAL(toml::get<toml::integer>(v3), 0xDEADBEEF);
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8"3.1415"_toml;
|
||||
const toml::value v2 = u8"6.02e+23"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_float());
|
||||
BOOST_CHECK(v2.is_float());
|
||||
BOOST_CHECK_CLOSE(toml::get<double>(v1), 3.1415, 0.00001);
|
||||
BOOST_CHECK_CLOSE(toml::get<double>(v2), 6.02e23, 0.0001);
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8R"("foo")"_toml;
|
||||
const toml::value v2 = u8R"('foo')"_toml;
|
||||
const toml::value v3 = u8R"("""foo""")"_toml;
|
||||
const toml::value v4 = u8R"('''foo''')"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_string());
|
||||
BOOST_CHECK(v2.is_string());
|
||||
BOOST_CHECK(v3.is_string());
|
||||
BOOST_CHECK(v4.is_string());
|
||||
BOOST_CHECK_EQUAL(toml::get<std::string>(v1), "foo");
|
||||
BOOST_CHECK_EQUAL(toml::get<std::string>(v2), "foo");
|
||||
BOOST_CHECK_EQUAL(toml::get<std::string>(v3), "foo");
|
||||
BOOST_CHECK_EQUAL(toml::get<std::string>(v4), "foo");
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8R"([1,2,3])"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_array());
|
||||
BOOST_CHECK((toml::get<std::vector<int>>(v1) == std::vector<int>{1,2,3}));
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8R"({a = 42})"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_table());
|
||||
BOOST_CHECK((toml::get<std::map<std::string,int>>(v1) ==
|
||||
std::map<std::string,int>{{"a", 42}}));
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8"1979-05-27"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_local_date());
|
||||
BOOST_CHECK_EQUAL(toml::get<toml::local_date>(v1),
|
||||
toml::local_date(1979, toml::month_t::May, 27));
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8"12:00:00"_toml;
|
||||
|
||||
BOOST_CHECK(v1.is_local_time());
|
||||
BOOST_CHECK(toml::get<std::chrono::hours>(v1) == std::chrono::hours(12));
|
||||
}
|
||||
{
|
||||
const toml::value v1 = u8"1979-05-27T07:32:00"_toml;
|
||||
BOOST_CHECK(v1.is_local_datetime());
|
||||
BOOST_CHECK_EQUAL(toml::get<toml::local_datetime>(v1),
|
||||
toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||
toml::local_time(7, 32, 0)));
|
||||
}
|
||||
{
|
||||
const toml::value v1 = "1979-05-27T07:32:00Z"_toml;
|
||||
BOOST_CHECK(v1.is_offset_datetime());
|
||||
BOOST_CHECK_EQUAL(toml::get<toml::offset_datetime>(v1),
|
||||
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
||||
}
|
||||
}
|
1
toml.hpp
1
toml.hpp
@@ -34,6 +34,7 @@
|
||||
#endif
|
||||
|
||||
#include "toml/parser.hpp"
|
||||
#include "toml/literal.hpp"
|
||||
#include "toml/serializer.hpp"
|
||||
#include "toml/from_toml.hpp"
|
||||
#include "toml/get.hpp"
|
||||
|
@@ -113,7 +113,7 @@ inline std::string get(value&& v)
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
detail::is_chrono_duration<T>::value, std::nullptr_t>::type = nullptr>
|
||||
inline T get(value& v)
|
||||
inline T get(const value& v)
|
||||
{
|
||||
return std::chrono::duration_cast<T>(
|
||||
std::chrono::nanoseconds(v.cast<value_t::LocalTime>()));
|
||||
@@ -125,7 +125,7 @@ inline T get(value& v)
|
||||
template<typename T, typename std::enable_if<
|
||||
std::is_same<std::chrono::system_clock::time_point, T>::value,
|
||||
std::nullptr_t>::type = nullptr>
|
||||
inline T get(value& v)
|
||||
inline T get(const value& v)
|
||||
{
|
||||
switch(v.type())
|
||||
{
|
||||
|
55
toml/literal.hpp
Normal file
55
toml/literal.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright Toru Niina 2019.
|
||||
// Distributed under the MIT License.
|
||||
#ifndef TOML11_LITERAL_HPP
|
||||
#define TOML11_LITERAL_HPP
|
||||
#include "parser.hpp"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
inline namespace literals
|
||||
{
|
||||
inline namespace toml_literals
|
||||
{
|
||||
|
||||
inline ::toml::value operator""_toml(const char* str, std::size_t len)
|
||||
{
|
||||
::toml::detail::location<std::vector<char>>
|
||||
loc(/* filename = */ std::string("TOML literal encoded in a C++ code"),
|
||||
/* contents = */ std::vector<char>(str, str + len));
|
||||
|
||||
// if there are some comments or empty lines, skip them.
|
||||
using skip_line = ::toml::detail::repeat<toml::detail::sequence<
|
||||
::toml::detail::maybe<::toml::detail::lex_ws>,
|
||||
::toml::detail::maybe<::toml::detail::lex_comment>,
|
||||
::toml::detail::lex_newline
|
||||
>, ::toml::detail::at_least<1>>;
|
||||
skip_line::invoke(loc);
|
||||
|
||||
// if there are some whitespaces before a value, skip them.
|
||||
using skip_ws = ::toml::detail::repeat<
|
||||
::toml::detail::lex_ws, ::toml::detail::at_least<1>>;
|
||||
skip_ws::invoke(loc);
|
||||
|
||||
// literal may be a bare value. try them first.
|
||||
if(auto data = ::toml::detail::parse_value(loc))
|
||||
{
|
||||
return data.unwrap();
|
||||
}
|
||||
|
||||
// literal is a TOML file (i.e. multiline table).
|
||||
if(auto data = ::toml::detail::parse_toml_file(loc))
|
||||
{
|
||||
loc.iter() = loc.begin(); // rollback to the top of the literal
|
||||
return ::toml::value(std::move(data.unwrap()),
|
||||
::toml::detail::region<std::vector<char>>(std::move(loc)));
|
||||
}
|
||||
else // none of them.
|
||||
{
|
||||
throw ::toml::syntax_error(data.unwrap_err());
|
||||
}
|
||||
}
|
||||
|
||||
} // toml_literals
|
||||
} // literals
|
||||
} // toml
|
||||
#endif//TOML11_LITERAL_HPP
|
Reference in New Issue
Block a user