mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-19 19:43:23 +08:00
cmJSONHelpers: Make error generators proper functions
This commit is contained in:
@@ -324,6 +324,7 @@ add_library(
|
|||||||
cmInstallTargetGenerator.cxx
|
cmInstallTargetGenerator.cxx
|
||||||
cmInstallDirectoryGenerator.h
|
cmInstallDirectoryGenerator.h
|
||||||
cmInstallDirectoryGenerator.cxx
|
cmInstallDirectoryGenerator.cxx
|
||||||
|
cmJSONHelpers.cxx
|
||||||
cmJSONHelpers.h
|
cmJSONHelpers.h
|
||||||
cmJSONState.cxx
|
cmJSONState.cxx
|
||||||
cmJSONState.h
|
cmJSONState.h
|
||||||
|
113
Source/cmJSONHelpers.cxx
Normal file
113
Source/cmJSONHelpers.cxx
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
file Copyright.txt 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(const std::string& type)
|
||||||
|
{
|
||||||
|
return [type](const Json::Value* 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(const Json::Value* value, cmJSONState* state)
|
||||||
|
{
|
||||||
|
JsonErrors::EXPECTED_TYPE("a string")(value, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void INVALID_BOOL(const Json::Value* value, cmJSONState* state)
|
||||||
|
{
|
||||||
|
JsonErrors::EXPECTED_TYPE("a bool")(value, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void INVALID_INT(const Json::Value* value, cmJSONState* state)
|
||||||
|
{
|
||||||
|
JsonErrors::EXPECTED_TYPE("an integer")(value, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void INVALID_UINT(const Json::Value* value, cmJSONState* state)
|
||||||
|
{
|
||||||
|
JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectErrorGenerator INVALID_NAMED_OBJECT(
|
||||||
|
const std::function<std::string(const Json::Value*, cmJSONState*)>&
|
||||||
|
nameGenerator)
|
||||||
|
{
|
||||||
|
return [nameGenerator](
|
||||||
|
ObjectError errorType,
|
||||||
|
const Json::Value::Members& extraFields) -> ErrorGenerator {
|
||||||
|
return [nameGenerator, errorType, extraFields](
|
||||||
|
const Json::Value* 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorGenerator INVALID_OBJECT(ObjectError errorType,
|
||||||
|
const Json::Value::Members& extraFields)
|
||||||
|
{
|
||||||
|
return INVALID_NAMED_OBJECT(
|
||||||
|
[](const Json::Value*, cmJSONState*) -> std::string { return "Object"; })(
|
||||||
|
errorType, extraFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorGenerator INVALID_NAMED_OBJECT_KEY(
|
||||||
|
ObjectError errorType, const Json::Value::Members& extraFields)
|
||||||
|
{
|
||||||
|
return INVALID_NAMED_OBJECT(
|
||||||
|
[](const Json::Value*, 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);
|
||||||
|
}
|
||||||
|
}
|
@@ -5,11 +5,11 @@
|
|||||||
#include "cmConfigure.h" // IWYU pragma: keep
|
#include "cmConfigure.h" // IWYU pragma: keep
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cm/optional>
|
#include <cm/optional>
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <cm3p/json/value.h>
|
#include <cm3p/json/value.h>
|
||||||
|
|
||||||
#include "cmJSONState.h"
|
#include "cmJSONState.h"
|
||||||
|
#include "cmStringAlgorithms.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using cmJSONHelper =
|
using cmJSONHelper =
|
||||||
@@ -36,94 +37,25 @@ enum ObjectError
|
|||||||
using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;
|
using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;
|
||||||
using ObjectErrorGenerator =
|
using ObjectErrorGenerator =
|
||||||
std::function<ErrorGenerator(ObjectError, const Json::Value::Members&)>;
|
std::function<ErrorGenerator(ObjectError, const Json::Value::Members&)>;
|
||||||
const auto EXPECTED_TYPE = [](const std::string& type) {
|
ErrorGenerator EXPECTED_TYPE(const std::string& type);
|
||||||
return [type](const Json::Value* value, cmJSONState* state) -> void {
|
|
||||||
if (state->key().empty()) {
|
void INVALID_STRING(const Json::Value* value, cmJSONState* state);
|
||||||
state->AddErrorAtValue(cmStrCat("Expected ", type), value);
|
|
||||||
return;
|
void INVALID_BOOL(const Json::Value* value, cmJSONState* state);
|
||||||
}
|
|
||||||
std::string errMsg = cmStrCat("\"", state->key(), "\" expected ", type);
|
void INVALID_INT(const Json::Value* value, cmJSONState* state);
|
||||||
if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
|
|
||||||
errMsg = cmStrCat(errMsg, ", got: ", value->asString());
|
void INVALID_UINT(const Json::Value* value, cmJSONState* state);
|
||||||
}
|
|
||||||
state->AddErrorAtValue(errMsg, value);
|
ObjectErrorGenerator INVALID_NAMED_OBJECT(
|
||||||
};
|
const std::function<std::string(const Json::Value*, cmJSONState*)>&
|
||||||
};
|
nameGenerator);
|
||||||
const auto INVALID_STRING = [](const Json::Value* value,
|
|
||||||
cmJSONState* state) -> void {
|
ErrorGenerator INVALID_OBJECT(ObjectError errorType,
|
||||||
JsonErrors::EXPECTED_TYPE("a string")(value, state);
|
const Json::Value::Members& extraFields);
|
||||||
};
|
|
||||||
const auto INVALID_BOOL = [](const Json::Value* value,
|
ErrorGenerator INVALID_NAMED_OBJECT_KEY(
|
||||||
cmJSONState* state) -> void {
|
ObjectError errorType, const Json::Value::Members& extraFields);
|
||||||
JsonErrors::EXPECTED_TYPE("a bool")(value, state);
|
|
||||||
};
|
|
||||||
const auto INVALID_INT = [](const Json::Value* value,
|
|
||||||
cmJSONState* state) -> void {
|
|
||||||
JsonErrors::EXPECTED_TYPE("an integer")(value, state);
|
|
||||||
};
|
|
||||||
const auto INVALID_UINT = [](const Json::Value* value,
|
|
||||||
cmJSONState* state) -> void {
|
|
||||||
JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
|
|
||||||
};
|
|
||||||
const auto INVALID_NAMED_OBJECT =
|
|
||||||
[](const std::function<std::string(const Json::Value*, cmJSONState*)>&
|
|
||||||
nameGenerator) -> ObjectErrorGenerator {
|
|
||||||
return [nameGenerator](
|
|
||||||
ObjectError errorType,
|
|
||||||
const Json::Value::Members& extraFields) -> ErrorGenerator {
|
|
||||||
return [nameGenerator, errorType, extraFields](
|
|
||||||
const Json::Value* 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const auto INVALID_OBJECT =
|
|
||||||
[](ObjectError errorType,
|
|
||||||
const Json::Value::Members& extraFields) -> ErrorGenerator {
|
|
||||||
return INVALID_NAMED_OBJECT(
|
|
||||||
[](const Json::Value*, cmJSONState*) -> std::string { return "Object"; })(
|
|
||||||
errorType, extraFields);
|
|
||||||
};
|
|
||||||
const auto INVALID_NAMED_OBJECT_KEY =
|
|
||||||
[](ObjectError errorType,
|
|
||||||
const Json::Value::Members& extraFields) -> ErrorGenerator {
|
|
||||||
return INVALID_NAMED_OBJECT(
|
|
||||||
[](const Json::Value*, 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);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmJSONHelperBuilder
|
struct cmJSONHelperBuilder
|
||||||
|
@@ -414,6 +414,7 @@ CMAKE_CXX_SOURCES="\
|
|||||||
cmInstallTargetGenerator \
|
cmInstallTargetGenerator \
|
||||||
cmInstallTargetsCommand \
|
cmInstallTargetsCommand \
|
||||||
cmInstalledFile \
|
cmInstalledFile \
|
||||||
|
cmJSONHelpers \
|
||||||
cmJSONState \
|
cmJSONState \
|
||||||
cmLDConfigLDConfigTool \
|
cmLDConfigLDConfigTool \
|
||||||
cmLDConfigTool \
|
cmLDConfigTool \
|
||||||
|
Reference in New Issue
Block a user