mirror of
https://github.com/nlohmann/json
synced 2025-01-15 03:30:04 +00:00
🚧 better diagnostics
This commit is contained in:
parent
68c3696382
commit
a4d491e22d
@ -1642,6 +1642,9 @@ class basic_json
|
||||
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
||||
{
|
||||
auto element = element_ref.moved_or_copied();
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
(*element.m_value.array)[1].m_parent = this;
|
||||
#endif
|
||||
m_value.object->emplace(
|
||||
std::move(*((*element.m_value.array)[0].m_value.string)),
|
||||
std::move((*element.m_value.array)[1]));
|
||||
@ -1652,6 +1655,12 @@ class basic_json
|
||||
// the initializer list describes an array -> create array
|
||||
m_type = value_t::array;
|
||||
m_value.array = create<array_t>(init.begin(), init.end());
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
for (auto& element : *m_value.array)
|
||||
{
|
||||
element.m_parent = this;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
assert_invariant();
|
||||
@ -2696,6 +2705,49 @@ class basic_json
|
||||
/// @}
|
||||
|
||||
private:
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
std::string diagnostics()
|
||||
{
|
||||
std::string result;
|
||||
for (basic_json* current = this; current->m_parent != nullptr; current = current->m_parent)
|
||||
{
|
||||
switch (current->m_parent->type())
|
||||
{
|
||||
case value_t::array:
|
||||
{
|
||||
for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
|
||||
{
|
||||
if (current->m_parent->m_value.array->operator[](i) == *current)
|
||||
{
|
||||
result = "/" + std::to_string(i) + result;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
for (auto it : *current->m_parent->m_value.object)
|
||||
{
|
||||
if (it.second == *current)
|
||||
{
|
||||
result = "/" + it.first + result;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////
|
||||
// value access //
|
||||
//////////////////
|
||||
@ -3318,7 +3370,13 @@ class basic_json
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.array->at(idx);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.array->at(idx);
|
||||
#endif
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
@ -3416,7 +3474,13 @@ class basic_json
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.object->at(key);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.object->at(key);
|
||||
#endif
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
@ -3525,9 +3589,18 @@ class basic_json
|
||||
m_value.array->insert(m_value.array->end(),
|
||||
idx - m_value.array->size() + 1,
|
||||
basic_json());
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.array->operator[](idx);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.array->operator[](idx);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||
@ -3603,7 +3676,13 @@ class basic_json
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.object->operator[](key);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.object->operator[](key);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
@ -3693,7 +3772,13 @@ class basic_json
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.object->operator[](key);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.object->operator[](key);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
@ -5249,6 +5334,9 @@ class basic_json
|
||||
|
||||
// add element to array (move semantics)
|
||||
m_value.array->push_back(std::move(val));
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
||||
}
|
||||
|
||||
@ -5284,6 +5372,9 @@ class basic_json
|
||||
|
||||
// add element to array
|
||||
m_value.array->push_back(val);
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5332,8 +5423,13 @@ class basic_json
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
// add element to array
|
||||
// add element to object
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
auto res = m_value.object->insert(val);
|
||||
res.first->second.m_parent = this;
|
||||
#else
|
||||
m_value.object->insert(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5437,9 +5533,18 @@ class basic_json
|
||||
|
||||
// add element to array (perfect forwarding)
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
#endif
|
||||
#else
|
||||
m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
return m_value.array->back();
|
||||
#endif
|
||||
}
|
||||
@ -6967,6 +7072,11 @@ class basic_json
|
||||
/// the value of the current element
|
||||
json_value m_value = {};
|
||||
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
/// a pointer to a parent value (for debugging purposes)
|
||||
basic_json* m_parent = nullptr;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////
|
||||
// binary serialization/deserialization //
|
||||
//////////////////////////////////////////
|
||||
|
@ -18266,6 +18266,9 @@ class basic_json
|
||||
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
||||
{
|
||||
auto element = element_ref.moved_or_copied();
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
(*element.m_value.array)[1].m_parent = this;
|
||||
#endif
|
||||
m_value.object->emplace(
|
||||
std::move(*((*element.m_value.array)[0].m_value.string)),
|
||||
std::move((*element.m_value.array)[1]));
|
||||
@ -18276,6 +18279,12 @@ class basic_json
|
||||
// the initializer list describes an array -> create array
|
||||
m_type = value_t::array;
|
||||
m_value.array = create<array_t>(init.begin(), init.end());
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
for (auto& element : *m_value.array)
|
||||
{
|
||||
element.m_parent = this;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
assert_invariant();
|
||||
@ -19320,6 +19329,49 @@ class basic_json
|
||||
/// @}
|
||||
|
||||
private:
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
std::string diagnostics()
|
||||
{
|
||||
std::string result;
|
||||
for (basic_json* current = this; current->m_parent != nullptr; current = current->m_parent)
|
||||
{
|
||||
switch (current->m_parent->type())
|
||||
{
|
||||
case value_t::array:
|
||||
{
|
||||
for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
|
||||
{
|
||||
if (current->m_parent->m_value.array->operator[](i) == *current)
|
||||
{
|
||||
result = "/" + std::to_string(i) + result;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
for (auto it : *current->m_parent->m_value.object)
|
||||
{
|
||||
if (it.second == *current)
|
||||
{
|
||||
result = "/" + it.first + result;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////
|
||||
// value access //
|
||||
//////////////////
|
||||
@ -19942,7 +19994,13 @@ class basic_json
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.array->at(idx);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.array->at(idx);
|
||||
#endif
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
@ -20040,7 +20098,13 @@ class basic_json
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.object->at(key);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.object->at(key);
|
||||
#endif
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
@ -20149,9 +20213,18 @@ class basic_json
|
||||
m_value.array->insert(m_value.array->end(),
|
||||
idx - m_value.array->size() + 1,
|
||||
basic_json());
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.array->operator[](idx);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.array->operator[](idx);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||
@ -20227,7 +20300,13 @@ class basic_json
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.object->operator[](key);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.object->operator[](key);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
@ -20317,7 +20396,13 @@ class basic_json
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.object->operator[](key);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.object->operator[](key);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
@ -21873,6 +21958,9 @@ class basic_json
|
||||
|
||||
// add element to array (move semantics)
|
||||
m_value.array->push_back(std::move(val));
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
||||
}
|
||||
|
||||
@ -21908,6 +21996,9 @@ class basic_json
|
||||
|
||||
// add element to array
|
||||
m_value.array->push_back(val);
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -21956,8 +22047,13 @@ class basic_json
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
// add element to array
|
||||
// add element to object
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
auto res = m_value.object->insert(val);
|
||||
res.first->second.m_parent = this;
|
||||
#else
|
||||
m_value.object->insert(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -22061,9 +22157,18 @@ class basic_json
|
||||
|
||||
// add element to array (perfect forwarding)
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
reference result = m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
result.m_parent = this;
|
||||
return result;
|
||||
#else
|
||||
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
#endif
|
||||
#else
|
||||
m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
m_value.array->back().m_parent = this;
|
||||
#endif
|
||||
return m_value.array->back();
|
||||
#endif
|
||||
}
|
||||
@ -23591,6 +23696,11 @@ class basic_json
|
||||
/// the value of the current element
|
||||
json_value m_value = {};
|
||||
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
/// a pointer to a parent value (for debugging purposes)
|
||||
basic_json* m_parent = nullptr;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////
|
||||
// binary serialization/deserialization //
|
||||
//////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user