mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 19:10:11 +08:00
add parse() function
This commit is contained in:
107
tests/test_parse_file.cpp
Normal file
107
tests/test_parse_file.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_parse_file"
|
||||||
|
#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 <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/example.toml");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(data.at("title")), "TOML Example");
|
||||||
|
toml::Table owner = toml::get<toml::Table>(data.at("owner"));
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("name")), "Tom Preston-Werner");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("organization")), "GitHub");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("bio")),
|
||||||
|
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<toml::Datetime>(owner.at("dob")),
|
||||||
|
toml::Datetime(1979, 5, 27, 7, 32, 0, 0, 0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
toml::Table database = toml::get<toml::Table>(data.at("database"));
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(database.at("server")), "192.168.1.1");
|
||||||
|
const std::vector<int> expected_ports{8001, 8001, 8002};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<int>>(database.at("ports")) == expected_ports);
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<int>(database.at("connection_max")), 5000);
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<bool>(database.at("enabled")), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
toml::Table servers = toml::get<toml::Table>(data.at("servers"));
|
||||||
|
{
|
||||||
|
toml::Table alpha = toml::get<toml::Table>(servers.at("alpha"));
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(alpha.at("ip")), "10.0.0.1");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(alpha.at("dc")), "eqdc10");
|
||||||
|
|
||||||
|
toml::Table beta = toml::get<toml::Table>(servers.at("beta"));
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("ip")), "10.0.0.2");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("dc")), "eqdc10");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("country")), "中国");
|
||||||
|
}
|
||||||
|
|
||||||
|
toml::Table clients = toml::get<toml::Table>(data.at("clients"));
|
||||||
|
{
|
||||||
|
toml::Array clients_data = toml::get<toml::Array>(clients.at("data"));
|
||||||
|
std::vector<std::string> expected_name{"gamma", "delta"};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) ==
|
||||||
|
expected_name);
|
||||||
|
std::vector<int> expected_number{1, 2};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) ==
|
||||||
|
expected_number);
|
||||||
|
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<std::string>>(clients.at("hosts")) ==
|
||||||
|
expected_hosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<toml::Table> products =
|
||||||
|
toml::get<std::vector<toml::Table>>(data.at("products"));
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(0).at("name")),
|
||||||
|
"Hammer");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(products.at(0).at("sku")),
|
||||||
|
738594937);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(1).at("name")),
|
||||||
|
"Nail");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(products.at(1).at("sku")),
|
||||||
|
284758393);
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(1).at("color")),
|
||||||
|
"gray");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_fruit)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/fruit.toml");
|
||||||
|
const auto blah = toml::get<std::vector<toml::Table>>(
|
||||||
|
toml::get<toml::Table>(data.at("fruit")).at("blah"));
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(blah.at(0).at("name")), "apple");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(blah.at(1).at("name")), "banana");
|
||||||
|
{
|
||||||
|
const auto physical = toml::get<toml::Table>(blah.at(0).at("physical"));
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("color")), "red");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("shape")), "round");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto physical = toml::get<toml::Table>(blah.at(1).at("physical"));
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("color")), "yellow");
|
||||||
|
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("shape")), "bent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOOST_AUTO_TEST_CASE(test_hard_example)
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
|
||||||
|
// {
|
||||||
|
// ;
|
||||||
|
// }
|
@@ -4,6 +4,7 @@
|
|||||||
#include "acceptor.hpp"
|
#include "acceptor.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
@@ -329,7 +330,15 @@ struct parse_float
|
|||||||
|
|
||||||
string_type result; result.resize(std::distance(iter, end));
|
string_type result; result.resize(std::distance(iter, end));
|
||||||
std::copy_if(iter, end, result.begin(), [](value_type c){return c != '_';});
|
std::copy_if(iter, end, result.begin(), [](value_type c){return c != '_';});
|
||||||
return std::make_pair(std::stod(result), end);
|
try{
|
||||||
|
return std::make_pair(std::stod(result), end);
|
||||||
|
}
|
||||||
|
catch(std::out_of_range& oor)
|
||||||
|
{
|
||||||
|
std::cout << "extremely large Float value appeared: "
|
||||||
|
<< result << "; it is negrected" << std::endl;
|
||||||
|
return std::make_pair(0, end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -929,7 +938,7 @@ struct parse_data
|
|||||||
if(iter == std::prev(end))
|
if(iter == std::prev(end))
|
||||||
{
|
{
|
||||||
if(data.count(*iter) == 1)
|
if(data.count(*iter) == 1)
|
||||||
throw syntax_error("duplicate key");
|
throw syntax_error("duplicate key: " + *iter);
|
||||||
data.emplace(*iter, std::move(v));
|
data.emplace(*iter, std::move(v));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -937,7 +946,7 @@ struct parse_data
|
|||||||
if(data.count(*iter) == 0)
|
if(data.count(*iter) == 0)
|
||||||
data.emplace(*iter, toml::Table());
|
data.emplace(*iter, toml::Table());
|
||||||
else if(data[*iter].type() != value_t::Table)
|
else if(data[*iter].type() != value_t::Table)
|
||||||
throw syntax_error("duplicate key");
|
throw syntax_error("duplicate key: " + *iter);
|
||||||
|
|
||||||
return push_table(data[*iter].template cast<value_t::Table>(),
|
return push_table(data[*iter].template cast<value_t::Table>(),
|
||||||
std::move(v), std::next(iter), end);
|
std::move(v), std::next(iter), end);
|
||||||
@@ -955,7 +964,7 @@ struct parse_data
|
|||||||
if(data.count(*iter) == 0)
|
if(data.count(*iter) == 0)
|
||||||
data.emplace(*iter, toml::Array());
|
data.emplace(*iter, toml::Array());
|
||||||
else if(data.at(*iter).type() != value_t::Array)
|
else if(data.at(*iter).type() != value_t::Array)
|
||||||
throw syntax_error("duplicate key");
|
throw syntax_error("duplicate key: " + *iter);
|
||||||
|
|
||||||
data[*iter].template cast<value_t::Array>().emplace_back(std::move(v));
|
data[*iter].template cast<value_t::Array>().emplace_back(std::move(v));
|
||||||
return;
|
return;
|
||||||
@@ -964,7 +973,7 @@ struct parse_data
|
|||||||
if(data.count(*iter) == 0)
|
if(data.count(*iter) == 0)
|
||||||
data.emplace(*iter, toml::Table());
|
data.emplace(*iter, toml::Table());
|
||||||
else if(data[*iter].type() != value_t::Table)
|
else if(data[*iter].type() != value_t::Table)
|
||||||
throw syntax_error("duplicate key");
|
throw syntax_error("duplicate key: " + *iter);
|
||||||
|
|
||||||
return push_array_of_table(data[*iter].template cast<value_t::Table>(),
|
return push_array_of_table(data[*iter].template cast<value_t::Table>(),
|
||||||
std::move(v), std::next(iter), end);
|
std::move(v), std::next(iter), end);
|
||||||
@@ -972,5 +981,26 @@ struct parse_data
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename traits = std::char_traits<toml::charactor>>
|
||||||
|
toml::Table parse(std::basic_istream<toml::charactor, traits>& is)
|
||||||
|
{
|
||||||
|
const auto initial = is.tellg();
|
||||||
|
is.seekg(0, std::ios::end);
|
||||||
|
const auto eofpos = is.tellg();
|
||||||
|
const std::size_t size = eofpos - initial;
|
||||||
|
is.seekg(initial);
|
||||||
|
std::vector<toml::charactor> contents(size);
|
||||||
|
is.read(contents.data(), size);
|
||||||
|
return parse_data::invoke(contents.cbegin(), contents.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
toml::Table parse(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::ifstream ifs(filename);
|
||||||
|
if(!ifs.good()) throw std::runtime_error("file open error: " + filename);
|
||||||
|
return parse(ifs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}// toml
|
}// toml
|
||||||
#endif// TOML11_PARSER
|
#endif// TOML11_PARSER
|
||||||
|
Reference in New Issue
Block a user