mirror of
https://github.com/nlohmann/json.git
synced 2026-10-31 18:05:44 +00:00
json_view: exceptions name the path and the bytes of the value
With JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS, the exceptions of views now carry the same context as those of basic_json: "(/path) " and "(bytes a-b) " in front of the message, in basic_json's format (with JSON_DIAGNOSTICS, no context for the root). Before, views threw without any context, and since get<T>() reads the view directly, conversions had lost even the relative path they used to get through materialize(). The throw helpers of detail/view/errors.hpp take an error_site (document and node; empty without the two macros). Only on the error path, the path is found by descending from the root (pruned by subtree extent before the first edit, a full walk through edited sequences after), and the bytes as materialize() sets them (position_source; a container's end by following the chain of last elements and scanning to the closing brackets). from_json() for views and the strict enum macro put the same context in front through exception_prefix(). Iterators keep their container only under the two macros, for key(). Without the macros, the accessors compile to the same code as before. Tests compare every value's exceptions with those of the parsed or materialized basic_json value, including edited documents; the checks that were disabled under the two macros run again. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
25 files changed
+1571
-710
No files matched your search
@@ -67,9 +67,17 @@ class view_iterator
|
||||
|
||||
/// @param[in] pos the element, or the key of the member
|
||||
/// @param[in] object whether pos is a key (its value is the next node)
|
||||
view_iterator(const document_data* d, const node* pos, bool object) noexcept
|
||||
/// @param[in] container the value iterated over (the context of the
|
||||
/// exceptions, kept only with JSON_DIAGNOSTICS or
|
||||
/// JSON_DIAGNOSTIC_POSITIONS)
|
||||
view_iterator(const document_data* d, const node* pos, bool object, const node* container) noexcept
|
||||
: m_doc(d), m_pos(pos), m_value_offset(object ? 1 : 0)
|
||||
{}
|
||||
#if JSON_DIAGNOSTICS || JSON_DIAGNOSTIC_POSITIONS
|
||||
, m_container(container)
|
||||
#endif
|
||||
{
|
||||
static_cast<void>(container);
|
||||
}
|
||||
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE View operator*() const noexcept
|
||||
{
|
||||
@@ -110,7 +118,7 @@ class view_iterator
|
||||
{
|
||||
if (NLOHMANN_VIEW_UNLIKELY(m_value_offset == 0))
|
||||
{
|
||||
throw_invalid_iterator(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators");
|
||||
throw_invalid_iterator(site(), exception_id::iterator_key_not_object, "cannot use key() for non-object iterators");
|
||||
}
|
||||
return string_view_t(m_doc->str(*m_pos), m_pos->len);
|
||||
}
|
||||
@@ -127,9 +135,22 @@ class view_iterator
|
||||
}
|
||||
|
||||
private:
|
||||
/// the value iterated over, as the context of an exception
|
||||
error_site site() const noexcept
|
||||
{
|
||||
#if JSON_DIAGNOSTICS || JSON_DIAGNOSTIC_POSITIONS
|
||||
return error_site(m_doc, m_container);
|
||||
#else
|
||||
return error_site();
|
||||
#endif
|
||||
}
|
||||
|
||||
const document_data* m_doc = nullptr;
|
||||
const node* m_pos = nullptr;
|
||||
std::size_t m_value_offset = 0; ///< 1 for objects: the value follows its key
|
||||
#if JSON_DIAGNOSTICS || JSON_DIAGNOSTIC_POSITIONS
|
||||
const node* m_container = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
Reference in new issue
Block a user