mirror of
https://github.com/nlohmann/json.git
synced 2026-07-10 12:35:09 +00:00
62 lines
1.6 KiB
C++
62 lines
1.6 KiB
C++
#include <iostream>
|
|
#include <nlohmann/json.hpp>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
using json = nlohmann::json;
|
|
|
|
json parse_strict(const std::string& input)
|
|
{
|
|
// one key set per nesting depth, reused across sibling objects
|
|
std::vector<std::unordered_set<std::string>> keys;
|
|
|
|
auto reject_duplicate_keys = [&](int depth, json::parse_event_t event, json & parsed)
|
|
{
|
|
if (event == json::parse_event_t::object_start)
|
|
{
|
|
// keys of this object are reported at depth+1 (see the event table above)
|
|
const auto child_depth = static_cast<std::size_t>(depth) + 1;
|
|
if (keys.size() <= child_depth)
|
|
{
|
|
keys.resize(child_depth + 1);
|
|
}
|
|
keys[child_depth].clear();
|
|
return true;
|
|
}
|
|
|
|
if (event == json::parse_event_t::key)
|
|
{
|
|
auto& seen = keys[static_cast<std::size_t>(depth)];
|
|
const auto& key = parsed.get_ref<const std::string&>();
|
|
if (!seen.insert(key).second)
|
|
{
|
|
throw std::runtime_error("duplicate JSON object key: " + key);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
return json::parse(input, reject_duplicate_keys);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
// parsing succeeds when all keys are unique
|
|
json j = parse_strict(R"({"one": 1, "two": 2})");
|
|
std::cout << j << '\n';
|
|
|
|
// parsing throws when a key is repeated
|
|
try
|
|
{
|
|
parse_strict(R"({"one": 1, "one": 2})");
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
std::cout << e.what() << '\n';
|
|
}
|
|
}
|