mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 02:08: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_inline_table
|
||||||
test_parse_key
|
test_parse_key
|
||||||
test_parse_table_key
|
test_parse_table_key
|
||||||
|
test_literals
|
||||||
test_get
|
test_get
|
||||||
test_get_related_func
|
test_get_related_func
|
||||||
test_from_toml
|
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
|
#endif
|
||||||
|
|
||||||
#include "toml/parser.hpp"
|
#include "toml/parser.hpp"
|
||||||
|
#include "toml/literal.hpp"
|
||||||
#include "toml/serializer.hpp"
|
#include "toml/serializer.hpp"
|
||||||
#include "toml/from_toml.hpp"
|
#include "toml/from_toml.hpp"
|
||||||
#include "toml/get.hpp"
|
#include "toml/get.hpp"
|
||||||
|
@@ -113,7 +113,7 @@ inline std::string get(value&& v)
|
|||||||
|
|
||||||
template<typename T, typename std::enable_if<
|
template<typename T, typename std::enable_if<
|
||||||
detail::is_chrono_duration<T>::value, std::nullptr_t>::type = nullptr>
|
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>(
|
return std::chrono::duration_cast<T>(
|
||||||
std::chrono::nanoseconds(v.cast<value_t::LocalTime>()));
|
std::chrono::nanoseconds(v.cast<value_t::LocalTime>()));
|
||||||
@@ -125,7 +125,7 @@ inline T get(value& v)
|
|||||||
template<typename T, typename std::enable_if<
|
template<typename T, typename std::enable_if<
|
||||||
std::is_same<std::chrono::system_clock::time_point, T>::value,
|
std::is_same<std::chrono::system_clock::time_point, T>::value,
|
||||||
std::nullptr_t>::type = nullptr>
|
std::nullptr_t>::type = nullptr>
|
||||||
inline T get(value& v)
|
inline T get(const value& v)
|
||||||
{
|
{
|
||||||
switch(v.type())
|
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