1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#include <iomanip>
#include <iostream>
#include <string>
#include <toml.hpp>
#include <nlohmann/json.hpp>
#include <cmath>
#ifdef TOML11_TO_JSON_USE_V1_1_0
# define TOML11_TO_JSON_SPEC toml::spec::v(1, 1, 0)
#else
# define TOML11_TO_JSON_SPEC toml::spec::v(1, 0, 0)
#endif
template<typename Value = toml::value>
struct json_converter
{
using value_type = Value;
using boolean_type = typename value_type::boolean_type ;
using integer_type = typename value_type::integer_type ;
using floating_type = typename value_type::floating_type ;
using string_type = typename value_type::string_type ;
using local_time_type = typename value_type::local_time_type ;
using local_date_type = typename value_type::local_date_type ;
using local_datetime_type = typename value_type::local_datetime_type ;
using offset_datetime_type = typename value_type::offset_datetime_type;
using array_type = typename value_type::array_type ;
using table_type = typename value_type::table_type ;
nlohmann::json operator()(boolean_type v)
{
nlohmann::json j;
j["type"] = "bool";
if(v)
{
j["value"] = "true";
}
else
{
j["value"] = "false";
}
return j;
}
nlohmann::json operator()(integer_type v)
{
nlohmann::json j;
j["type"] = "integer";
j["value"] = std::to_string(v);
return j;
}
nlohmann::json operator()(floating_type v)
{
std::ostringstream oss;
oss << std::setprecision(16);
// if we set the precision as max_digit, 1.1 will be 1.1000000000000001.
// But toml-test does not allow 1.1000000000000001.
if(std::isnan(v) && std::signbit(v))
{
// toml-test does not allow negative NaN represented in "-nan" because
// there are languages that does not distinguish nan and -nan.
// But toml11 keeps sign from input. To resolve this difference,
// we convert -nan to nan here.
v = std::numeric_limits<floating_type>::quiet_NaN();
}
oss << v;
nlohmann::json j;
j["type"] = "float";
j["value"] = oss.str();
return j;
}
nlohmann::json operator()(const string_type& v)
{
nlohmann::json j;
j["type"] = "string";
j["value"] = v;
return j;
}
nlohmann::json operator()(const toml::local_time& v)
{
nlohmann::json j;
j["type"] = "time-local";
j["value"] = toml::to_string(v);
return j;
}
nlohmann::json operator()(const toml::local_date& v)
{
nlohmann::json j;
j["type"] = "date-local";
j["value"] = toml::to_string(v);
return j;
}
nlohmann::json operator()(const toml::local_datetime& v)
{
nlohmann::json j;
j["type"] = "datetime-local";
j["value"] = toml::to_string(v);
return j;
}
nlohmann::json operator()(const toml::offset_datetime& v)
{
nlohmann::json j;
j["type"] = "datetime";
j["value"] = toml::to_string(v);
return j;
}
nlohmann::json operator()(const toml::array& v)
{
nlohmann::json j = nlohmann::json::array();
for(const auto& elem : v)
{
j.push_back(toml::visit(*this, elem));
}
return j;
}
nlohmann::json operator()(const toml::table& v)
{
nlohmann::json j = nlohmann::json::object();
for(const auto& kv : v)
{
j[kv.first] = toml::visit(*this, kv.second);
}
return j;
}
};
int main(int argc, char** argv)
{
try
{
if(argc == 2)
{
const std::string fname(argv[1]);
const auto data = toml::parse(fname, TOML11_TO_JSON_SPEC);
std::cout << toml::visit(json_converter<>(), data);
return 0;
}
else
{
std::vector<unsigned char> buf;
std::cin.peek();
while(!std::cin.eof())
{
buf.push_back(static_cast<unsigned char>(std::cin.get()));
std::cin.peek();
}
const auto data = toml::parse(buf, "cin", TOML11_TO_JSON_SPEC);
std::cout << toml::visit(json_converter<>(), data);
return 0;
}
}
catch(const std::exception& err)
{
std::cout << "what(): " << err.what() << std::endl;
return 1;
}
}
|