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
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmJSONHelpers.h"
#include <functional>
#include <string>
#include <vector>
#include <cm3p/json/value.h>
#include "cmJSONState.h"
namespace JsonErrors {
ErrorGenerator EXPECTED_TYPE(std::string const& type)
{
return [type](Json::Value const* value, cmJSONState* state) -> void {
if (state->key().empty()) {
state->AddErrorAtValue(cmStrCat("Expected ", type), value);
return;
}
std::string errMsg = cmStrCat('"', state->key(), "\" expected ", type);
if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
errMsg = cmStrCat(errMsg, ", got: ", value->asString());
}
state->AddErrorAtValue(errMsg, value);
};
}
void INVALID_STRING(Json::Value const* value, cmJSONState* state)
{
JsonErrors::EXPECTED_TYPE("a string")(value, state);
}
void INVALID_BOOL(Json::Value const* value, cmJSONState* state)
{
JsonErrors::EXPECTED_TYPE("a bool")(value, state);
}
void INVALID_INT(Json::Value const* value, cmJSONState* state)
{
JsonErrors::EXPECTED_TYPE("an integer")(value, state);
}
void INVALID_UINT(Json::Value const* value, cmJSONState* state)
{
JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
}
ObjectErrorGenerator INVALID_NAMED_OBJECT(
std::function<std::string(Json::Value const*, cmJSONState*)> const&
nameGenerator)
{
#if defined(__GNUC__) && __GNUC__ >= 15
# define CM_GCC_diagnostic_push_Wmaybe_uninitialized
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
return [nameGenerator](
ObjectError errorType,
Json::Value::Members const& extraFields) -> ErrorGenerator {
return [nameGenerator, errorType, extraFields](
Json::Value const* value, cmJSONState* state) -> void {
std::string name = nameGenerator(value, state);
switch (errorType) {
case ObjectError::RequiredMissing:
state->AddErrorAtValue(cmStrCat("Invalid Required ", name), value);
break;
case ObjectError::InvalidObject:
state->AddErrorAtValue(cmStrCat("Invalid ", name), value);
break;
case ObjectError::ExtraField: {
for (auto const& member : extraFields) {
if (value) {
state->AddErrorAtValue(
cmStrCat("Invalid extra field \"", member, "\" in ", name),
&(*value)[member]);
} else {
state->AddError(
cmStrCat("Invalid extra field \"", member, "\" in ", name));
}
}
} break;
case ObjectError::MissingRequired:
state->AddErrorAtValue(cmStrCat("Missing required field \"",
state->key(), "\" in ", name),
value);
break;
}
};
};
#ifdef CM_GCC_diagnostic_push_Wmaybe_uninitialized
# pragma GCC diagnostic pop
# undef CM_GCC_diagnostic_push_Wmaybe_uninitialized
#endif
}
ErrorGenerator INVALID_OBJECT(ObjectError errorType,
Json::Value::Members const& extraFields)
{
return INVALID_NAMED_OBJECT(
[](Json::Value const*, cmJSONState*) -> std::string { return "Object"; })(
errorType, extraFields);
}
ErrorGenerator INVALID_NAMED_OBJECT_KEY(
ObjectError errorType, Json::Value::Members const& extraFields)
{
return INVALID_NAMED_OBJECT(
[](Json::Value const*, cmJSONState* state) -> std::string {
for (auto it = state->parseStack.rbegin();
it != state->parseStack.rend(); ++it) {
if (it->first.rfind("$vector_item_", 0) == 0) {
continue;
}
return cmStrCat('"', it->first, '"');
}
return "root";
})(errorType, extraFields);
}
}
|