diff options
author | Martin Duffy <martin.duffy@kitware.com> | 2022-05-04 18:03:07 -0400 |
---|---|---|
committer | Martin Duffy <martin.duffy@kitware.com> | 2022-05-05 12:12:12 -0400 |
commit | 30336dab664979e66745f5bcca16c73a4cafccca (patch) | |
tree | 78631d571d05c88782a7d97d00cd1bc1f9fddfff | |
parent | 7d78dcbebbb028c17de38e337942e0df061c6f20 (diff) | |
download | cmake-30336dab664979e66745f5bcca16c73a4cafccca.tar.gz |
cmJSONHelpers: Restructure cmJSONHelpers
Restructure cmJSONHelpers to prevent SunPro errors when passing context.
-rw-r--r-- | Source/CTest/cmCTestResourceSpec.cxx | 53 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraphReadJSON.cxx | 95 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx | 7 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx | 24 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraphReadJSONTestPresets.cxx | 66 | ||||
-rw-r--r-- | Source/cmJSONHelpers.h | 477 | ||||
-rw-r--r-- | Tests/CMakeLib/testJSONHelpers.cxx | 47 |
7 files changed, 362 insertions, 407 deletions
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx index 101dc2c8b5..142b07de1a 100644 --- a/Source/CTest/cmCTestResourceSpec.cxx +++ b/Source/CTest/cmCTestResourceSpec.cxx @@ -19,6 +19,8 @@ #include "cmJSONHelpers.h" namespace { +using JSONHelperBuilder = + cmJSONHelperBuilder<cmCTestResourceSpec::ReadFileResult>; const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" }; const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" }; @@ -34,21 +36,19 @@ struct TopVersion }; auto const VersionFieldHelper = - cmJSONIntHelper<cmCTestResourceSpec::ReadFileResult>( - cmCTestResourceSpec::ReadFileResult::READ_OK, - cmCTestResourceSpec::ReadFileResult::INVALID_VERSION); + JSONHelperBuilder::Int(cmCTestResourceSpec::ReadFileResult::READ_OK, + cmCTestResourceSpec::ReadFileResult::INVALID_VERSION); -auto const VersionHelper = - cmJSONRequiredHelper<Version, cmCTestResourceSpec::ReadFileResult>( - cmCTestResourceSpec::ReadFileResult::NO_VERSION, - cmJSONObjectHelper<Version, cmCTestResourceSpec::ReadFileResult>( - cmCTestResourceSpec::ReadFileResult::READ_OK, - cmCTestResourceSpec::ReadFileResult::INVALID_VERSION) - .Bind("major"_s, &Version::Major, VersionFieldHelper) - .Bind("minor"_s, &Version::Minor, VersionFieldHelper)); +auto const VersionHelper = JSONHelperBuilder::Required<Version>( + cmCTestResourceSpec::ReadFileResult::NO_VERSION, + JSONHelperBuilder::Object<Version>( + cmCTestResourceSpec::ReadFileResult::READ_OK, + cmCTestResourceSpec::ReadFileResult::INVALID_VERSION) + .Bind("major"_s, &Version::Major, VersionFieldHelper) + .Bind("minor"_s, &Version::Minor, VersionFieldHelper)); auto const RootVersionHelper = - cmJSONObjectHelper<TopVersion, cmCTestResourceSpec::ReadFileResult>( + JSONHelperBuilder::Object<TopVersion>( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_ROOT) .Bind("version"_s, &TopVersion::Version, VersionHelper, false); @@ -56,7 +56,7 @@ auto const RootVersionHelper = cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out, const Json::Value* value) { - auto result = cmJSONStringHelper( + auto result = JSONHelperBuilder::String( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)(out, value); if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) { @@ -70,27 +70,24 @@ cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out, } auto const ResourceHelper = - cmJSONObjectHelper<cmCTestResourceSpec::Resource, - cmCTestResourceSpec::ReadFileResult>( + JSONHelperBuilder::Object<cmCTestResourceSpec::Resource>( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE) .Bind("id"_s, &cmCTestResourceSpec::Resource::Id, ResourceIdHelper) .Bind("slots"_s, &cmCTestResourceSpec::Resource::Capacity, - cmJSONUIntHelper( + JSONHelperBuilder::UInt( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, 1), false); auto const ResourceListHelper = - cmJSONVectorHelper<cmCTestResourceSpec::Resource, - cmCTestResourceSpec::ReadFileResult>( + JSONHelperBuilder::Vector<cmCTestResourceSpec::Resource>( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE_TYPE, ResourceHelper); auto const ResourceMapHelper = - cmJSONMapFilterHelper<std::vector<cmCTestResourceSpec::Resource>, - cmCTestResourceSpec::ReadFileResult>( + JSONHelperBuilder::MapFilter<std::vector<cmCTestResourceSpec::Resource>>( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, ResourceListHelper, [](const std::string& key) -> bool { @@ -98,7 +95,7 @@ auto const ResourceMapHelper = return IdentifierRegex.find(key.c_str(), match); }); -auto const SocketSetHelper = cmJSONVectorHelper< +auto const SocketSetHelper = JSONHelperBuilder::Vector< std::map<std::string, std::vector<cmCTestResourceSpec::Resource>>>( cmCTestResourceSpec::ReadFileResult::READ_OK, cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, ResourceMapHelper); @@ -125,16 +122,14 @@ cmCTestResourceSpec::ReadFileResult SocketHelper( } auto const LocalRequiredHelper = - cmJSONRequiredHelper<cmCTestResourceSpec::Socket, - cmCTestResourceSpec::ReadFileResult>( + JSONHelperBuilder::Required<cmCTestResourceSpec::Socket>( cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, SocketHelper); -auto const RootHelper = - cmJSONObjectHelper<cmCTestResourceSpec, cmCTestResourceSpec::ReadFileResult>( - cmCTestResourceSpec::ReadFileResult::READ_OK, - cmCTestResourceSpec::ReadFileResult::INVALID_ROOT) - .Bind("local", &cmCTestResourceSpec::LocalSocket, LocalRequiredHelper, - false); +auto const RootHelper = JSONHelperBuilder::Object<cmCTestResourceSpec>( + cmCTestResourceSpec::ReadFileResult::READ_OK, + cmCTestResourceSpec::ReadFileResult::INVALID_ROOT) + .Bind("local", &cmCTestResourceSpec::LocalSocket, + LocalRequiredHelper, false); } cmCTestResourceSpec::ReadFileResult cmCTestResourceSpec::ReadFromJSONFile( diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx index 0d3a91fd3e..d11e839f0b 100644 --- a/Source/cmCMakePresetsGraphReadJSON.cxx +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -31,6 +31,7 @@ using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; using BuildPreset = cmCMakePresetsGraph::BuildPreset; using TestPreset = cmCMakePresetsGraph::TestPreset; using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; +using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>; constexpr int MIN_VERSION = 1; constexpr int MAX_VERSION = 5; @@ -59,29 +60,26 @@ std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition( return retval; } -auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>( +auto const ConditionStringHelper = JSONHelperBuilder::String( ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); -auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>( +auto const ConditionBoolHelper = JSONHelperBuilder::Bool( ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); -auto const ConditionStringListHelper = - cmJSONVectorHelper<std::string, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, - ConditionStringHelper); +auto const ConditionStringListHelper = JSONHelperBuilder::Vector<std::string>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, + ConditionStringHelper); auto const ConstConditionHelper = - cmJSONObjectHelper<cmCMakePresetsGraphInternal::ConstCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) + JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::ConstCondition>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) .Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value, ConditionBoolHelper, true); auto const EqualsConditionHelper = - cmJSONObjectHelper<cmCMakePresetsGraphInternal::EqualsCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) + JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::EqualsCondition>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) .Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs, ConditionStringHelper, true) @@ -89,9 +87,8 @@ auto const EqualsConditionHelper = ConditionStringHelper, true); auto const InListConditionHelper = - cmJSONObjectHelper<cmCMakePresetsGraphInternal::InListCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) + JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::InListCondition>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) .Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String, ConditionStringHelper, true) @@ -99,9 +96,8 @@ auto const InListConditionHelper = ConditionStringListHelper, true); auto const MatchesConditionHelper = - cmJSONObjectHelper<cmCMakePresetsGraphInternal::MatchesCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) + JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::MatchesCondition>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) .Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String, ConditionStringHelper, true) @@ -113,23 +109,20 @@ ReadFileResult SubConditionHelper( const Json::Value* value); auto const ListConditionVectorHelper = - cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsGraph::Condition>, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, - SubConditionHelper); + JSONHelperBuilder::Vector<std::unique_ptr<cmCMakePresetsGraph::Condition>>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, + SubConditionHelper); auto const AnyAllOfConditionHelper = - cmJSONObjectHelper<cmCMakePresetsGraphInternal::AnyAllOfCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) + JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::AnyAllOfCondition>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) .Bind("conditions"_s, &cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions, ListConditionVectorHelper); auto const NotConditionHelper = - cmJSONObjectHelper<cmCMakePresetsGraphInternal::NotCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) + JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::NotCondition>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) .Bind("condition"_s, &cmCMakePresetsGraphInternal::NotCondition::SubCondition, @@ -251,37 +244,36 @@ ReadFileResult EnvironmentHelper(cm::optional<std::string>& out, return ReadFileResult::INVALID_PRESET; } -auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>( +auto const VersionIntHelper = JSONHelperBuilder::Int( ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); -auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>( +auto const VersionHelper = JSONHelperBuilder::Required<int>( ReadFileResult::NO_VERSION, VersionIntHelper); auto const RootVersionHelper = - cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_ROOT) + JSONHelperBuilder::Object<int>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_ROOT) .Bind("version"_s, VersionHelper, false); -auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>( +auto const CMakeVersionUIntHelper = JSONHelperBuilder::UInt( ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); auto const CMakeVersionHelper = - cmJSONObjectHelper<CMakeVersion, ReadFileResult>( + JSONHelperBuilder::Object<CMakeVersion>( ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); -auto const IncludeHelper = cmJSONStringHelper<ReadFileResult>( +auto const IncludeHelper = JSONHelperBuilder::String( ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE); -auto const IncludeVectorHelper = - cmJSONVectorHelper<std::string, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper); +auto const IncludeVectorHelper = JSONHelperBuilder::Vector<std::string>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper); auto const RootPresetsHelper = - cmJSONObjectHelper<RootPresets, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) + JSONHelperBuilder::Object<RootPresets>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_ROOT, false) .Bind<int>("version"_s, nullptr, VersionHelper) .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false) @@ -302,7 +294,7 @@ namespace cmCMakePresetsGraphInternal { cmCMakePresetsGraph::ReadFileResult PresetStringHelper( std::string& out, const Json::Value* value) { - static auto const helper = cmJSONStringHelper<ReadFileResult>( + static auto const helper = JSONHelperBuilder::String( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); return helper(out, value); @@ -311,7 +303,7 @@ cmCMakePresetsGraph::ReadFileResult PresetStringHelper( cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper( std::vector<std::string>& out, const Json::Value* value) { - static auto const helper = cmJSONVectorHelper<std::string, ReadFileResult>( + static auto const helper = JSONHelperBuilder::Vector<std::string>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, cmCMakePresetsGraphInternal::PresetStringHelper); @@ -321,7 +313,7 @@ cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper( cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out, const Json::Value* value) { - static auto const helper = cmJSONBoolHelper<ReadFileResult>( + static auto const helper = JSONHelperBuilder::Bool( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); return helper(out, value); @@ -330,7 +322,7 @@ cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out, cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper( cm::optional<bool>& out, const Json::Value* value) { - static auto const helper = cmJSONOptionalHelper<bool, ReadFileResult>( + static auto const helper = JSONHelperBuilder::Optional<bool>( ReadFileResult::READ_OK, PresetBoolHelper); return helper(out, value); @@ -339,7 +331,7 @@ cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper( cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out, const Json::Value* value) { - static auto const helper = cmJSONIntHelper<ReadFileResult>( + static auto const helper = JSONHelperBuilder::Int( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); return helper(out, value); @@ -348,8 +340,8 @@ cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out, cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper( cm::optional<int>& out, const Json::Value* value) { - static auto const helper = cmJSONOptionalHelper<int, ReadFileResult>( - ReadFileResult::READ_OK, PresetIntHelper); + static auto const helper = + JSONHelperBuilder::Optional<int>(ReadFileResult::READ_OK, PresetIntHelper); return helper(out, value); } @@ -357,7 +349,7 @@ cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper( cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper( std::vector<int>& out, const Json::Value* value) { - static auto const helper = cmJSONVectorHelper<int, ReadFileResult>( + static auto const helper = JSONHelperBuilder::Vector<int>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); return helper(out, value); @@ -409,10 +401,9 @@ cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper( std::map<std::string, cm::optional<std::string>>& out, const Json::Value* value) { - static auto const helper = - cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - EnvironmentHelper); + static auto const helper = JSONHelperBuilder::Map<cm::optional<std::string>>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + EnvironmentHelper); return helper(out, value); } diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx index eefe2fe28a..430d7ee3a2 100644 --- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx +++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx @@ -20,6 +20,7 @@ namespace { using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; using BuildPreset = cmCMakePresetsGraph::BuildPreset; +using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>; ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out, const Json::Value* value) @@ -53,8 +54,8 @@ std::function<ReadFileResult(BuildPreset&, const Json::Value*)> const }; auto const BuildPresetHelper = - cmJSONObjectHelper<BuildPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + JSONHelperBuilder::Object<BuildPreset>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET, false) .Bind("name"_s, &BuildPreset::Name, cmCMakePresetsGraphInternal::PresetStringHelper) .Bind("inherits"_s, &BuildPreset::Inherits, @@ -99,7 +100,7 @@ namespace cmCMakePresetsGraphInternal { ReadFileResult BuildPresetsHelper(std::vector<BuildPreset>& out, const Json::Value* value) { - static auto const helper = cmJSONVectorHelper<BuildPreset, ReadFileResult>( + static auto const helper = JSONHelperBuilder::Vector<BuildPreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, BuildPresetHelper); diff --git a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx index 0f44546f4d..7cff55a01b 100644 --- a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx +++ b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx @@ -21,6 +21,7 @@ using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; using CacheVariable = cmCMakePresetsGraph::CacheVariable; using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; +using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>; ReadFileResult ArchToolsetStrategyHelper( cm::optional<ArchToolsetStrategy>& out, const Json::Value* value) @@ -53,7 +54,7 @@ ArchToolsetHelper( cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) { auto const objectHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + JSONHelperBuilder::Object<ConfigurePreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) .Bind("value", valueField, cmCMakePresetsGraphInternal::PresetStringHelper, false) @@ -85,7 +86,7 @@ auto const ArchitectureHelper = ArchToolsetHelper( auto const ToolsetHelper = ArchToolsetHelper( &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); -auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( +auto const VariableStringHelper = JSONHelperBuilder::String( ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) @@ -104,7 +105,7 @@ ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) } auto const VariableObjectHelper = - cmJSONObjectHelper<CacheVariable, ReadFileResult>( + JSONHelperBuilder::Object<CacheVariable>( ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); @@ -138,11 +139,11 @@ ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, } auto const VariablesHelper = - cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>( + JSONHelperBuilder::Map<cm::optional<CacheVariable>>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); auto const PresetWarningsHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + JSONHelperBuilder::Object<ConfigurePreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) .Bind("dev"_s, &ConfigurePreset::WarnDev, cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) @@ -156,7 +157,7 @@ auto const PresetWarningsHelper = cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); auto const PresetErrorsHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + JSONHelperBuilder::Object<ConfigurePreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) .Bind("dev"_s, &ConfigurePreset::ErrorDev, cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) @@ -164,7 +165,7 @@ auto const PresetErrorsHelper = cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); auto const PresetDebugHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + JSONHelperBuilder::Object<ConfigurePreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) .Bind("output"_s, &ConfigurePreset::DebugOutput, cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) @@ -174,7 +175,7 @@ auto const PresetDebugHelper = cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); auto const ConfigurePresetHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + JSONHelperBuilder::Object<ConfigurePreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) .Bind("name"_s, &ConfigurePreset::Name, cmCMakePresetsGraphInternal::PresetStringHelper) @@ -218,10 +219,9 @@ namespace cmCMakePresetsGraphInternal { ReadFileResult ConfigurePresetsHelper(std::vector<ConfigurePreset>& out, const Json::Value* value) { - static auto const helper = - cmJSONVectorHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - ConfigurePresetHelper); + static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + ConfigurePresetHelper); return helper(out, value); } diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx index b87457506d..c07d380260 100644 --- a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx +++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx @@ -21,6 +21,7 @@ namespace { using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; using TestPreset = cmCMakePresetsGraph::TestPreset; +using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>; ReadFileResult TestPresetOutputVerbosityHelper( TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) @@ -53,9 +54,8 @@ ReadFileResult TestPresetOutputVerbosityHelper( } auto const TestPresetOptionalOutputVerbosityHelper = - cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetOutputVerbosityHelper); + JSONHelperBuilder::Optional<TestPreset::OutputOptions::VerbosityEnum>( + ReadFileResult::READ_OK, TestPresetOutputVerbosityHelper); ReadFileResult TestPresetOutputTruncationHelper( cm::optional<cmCTestTypes::TruncationMode>& out, const Json::Value* value) @@ -88,9 +88,9 @@ ReadFileResult TestPresetOutputTruncationHelper( } auto const TestPresetOptionalOutputHelper = - cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::OutputOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>( + JSONHelperBuilder::Object<TestPreset::OutputOptions>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) @@ -122,12 +122,10 @@ auto const TestPresetOptionalOutputHelper = cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)); auto const TestPresetOptionalFilterIncludeIndexObjectHelper = - cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions, - ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::IncludeOptions::IndexOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) + JSONHelperBuilder::Object<TestPreset::IncludeOptions::IndexOptions>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, @@ -161,9 +159,9 @@ ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( } auto const TestPresetOptionalFilterIncludeHelper = - cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::IncludeOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>( + JSONHelperBuilder::Object<TestPreset::IncludeOptions>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("name"_s, &TestPreset::IncludeOptions::Name, cmCMakePresetsGraphInternal::PresetStringHelper, false) @@ -175,12 +173,10 @@ auto const TestPresetOptionalFilterIncludeHelper = cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)); auto const TestPresetOptionalFilterExcludeFixturesHelper = - cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions, - ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::ExcludeOptions::FixturesOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) + JSONHelperBuilder::Object<TestPreset::ExcludeOptions::FixturesOptions>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, cmCMakePresetsGraphInternal::PresetStringHelper, false) .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, @@ -189,9 +185,9 @@ auto const TestPresetOptionalFilterExcludeFixturesHelper = cmCMakePresetsGraphInternal::PresetStringHelper, false)); auto const TestPresetOptionalFilterExcludeHelper = - cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::ExcludeOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>( + JSONHelperBuilder::Object<TestPreset::ExcludeOptions>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("name"_s, &TestPreset::ExcludeOptions::Name, cmCMakePresetsGraphInternal::PresetStringHelper, false) @@ -221,9 +217,8 @@ ReadFileResult TestPresetExecutionShowOnlyHelper( } auto const TestPresetOptionalExecutionShowOnlyHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetExecutionShowOnlyHelper); + JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::ShowOnlyEnum>( + ReadFileResult::READ_OK, TestPresetExecutionShowOnlyHelper); ReadFileResult TestPresetExecutionModeHelper( TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, @@ -256,12 +251,10 @@ ReadFileResult TestPresetExecutionModeHelper( } auto const TestPresetOptionalExecutionRepeatHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions, - ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::RepeatOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) + JSONHelperBuilder::Object<TestPreset::ExecutionOptions::RepeatOptions>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, TestPresetExecutionModeHelper, true) .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, @@ -299,14 +292,13 @@ ReadFileResult TestPresetExecutionNoTestsActionHelper( } auto const TestPresetOptionalExecutionNoTestsActionHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetExecutionNoTestsActionHelper); + JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::NoTestsActionEnum>( + ReadFileResult::READ_OK, TestPresetExecutionNoTestsActionHelper); auto const TestPresetExecutionHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::ExecutionOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>( + JSONHelperBuilder::Object<TestPreset::ExecutionOptions>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) @@ -334,9 +326,9 @@ auto const TestPresetExecutionHelper = TestPresetOptionalExecutionNoTestsActionHelper, false)); auto const TestPresetFilterHelper = - cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>( + JSONHelperBuilder::Optional<TestPreset::FilterOptions>( ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>( + JSONHelperBuilder::Object<TestPreset::FilterOptions>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) .Bind("include"_s, &TestPreset::FilterOptions::Include, TestPresetOptionalFilterIncludeHelper, false) @@ -344,8 +336,8 @@ auto const TestPresetFilterHelper = TestPresetOptionalFilterExcludeHelper, false)); auto const TestPresetHelper = - cmJSONObjectHelper<TestPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + JSONHelperBuilder::Object<TestPreset>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET, false) .Bind("name"_s, &TestPreset::Name, cmCMakePresetsGraphInternal::PresetStringHelper) .Bind("inherits"_s, &TestPreset::Inherits, @@ -386,7 +378,7 @@ namespace cmCMakePresetsGraphInternal { cmCMakePresetsGraph::ReadFileResult TestPresetsHelper( std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value) { - static auto const helper = cmJSONVectorHelper<TestPreset, ReadFileResult>( + static auto const helper = JSONHelperBuilder::Vector<TestPreset>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, TestPresetHelper); diff --git a/Source/cmJSONHelpers.h b/Source/cmJSONHelpers.h index 6690aef848..42532ebb82 100644 --- a/Source/cmJSONHelpers.h +++ b/Source/cmJSONHelpers.h @@ -17,143 +17,119 @@ template <typename T, typename E> using cmJSONHelper = std::function<E(T& out, const Json::Value* value)>; -template <typename T, typename E> -class cmJSONObjectHelper +template <typename E> +struct cmJSONHelperBuilder { -public: - cmJSONObjectHelper(E&& success, E&& fail, bool allowExtra = true); - - template <typename U, typename M, typename F> - cmJSONObjectHelper& Bind(const cm::string_view& name, M U::*member, F func, - bool required = true); - template <typename M, typename F> - cmJSONObjectHelper& Bind(const cm::string_view& name, std::nullptr_t, F func, - bool required = true); - template <typename F> - cmJSONObjectHelper& Bind(const cm::string_view& name, F func, - bool required = true); - - E operator()(T& out, const Json::Value* value) const; - -private: - // Not a true cmJSONHelper, it just happens to match the signature - using MemberFunction = std::function<E(T& out, const Json::Value* value)>; - struct Member + template <typename T> + class Object { - cm::string_view Name; - MemberFunction Function; - bool Required; - }; - std::vector<Member> Members; - bool AnyRequired = false; - E Success; - E Fail; - bool AllowExtra; - - cmJSONObjectHelper& BindPrivate(const cm::string_view& name, - MemberFunction&& func, bool required); -}; - -template <typename T, typename E> -cmJSONObjectHelper<T, E>::cmJSONObjectHelper(E&& success, E&& fail, - bool allowExtra) - : Success(std::move(success)) - , Fail(std::move(fail)) - , AllowExtra(allowExtra) -{ -} + public: + Object(E&& success, E&& fail, bool allowExtra = true) + : Success(std::move(success)) + , Fail(std::move(fail)) + , AllowExtra(allowExtra) + { + } -template <typename T, typename E> -template <typename U, typename M, typename F> -cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind( - const cm::string_view& name, M U::*member, F func, bool required) -{ - return this->BindPrivate( - name, - [func, member](T& out, const Json::Value* value) -> E { - return func(out.*member, value); - }, - required); -} + template <typename U, typename M, typename F> + Object& Bind(const cm::string_view& name, M U::*member, F func, + bool required = true) + { + return this->BindPrivate( + name, + [func, member](T& out, const Json::Value* value) -> E { + return func(out.*member, value); + }, + required); + } + template <typename M, typename F> + Object& Bind(const cm::string_view& name, std::nullptr_t, F func, + bool required = true) + { + return this->BindPrivate( + name, + [func](T& /*out*/, const Json::Value* value) -> E { + M dummy; + return func(dummy, value); + }, + required); + } + template <typename F> + Object& Bind(const cm::string_view& name, F func, bool required = true) + { + return this->BindPrivate(name, MemberFunction(func), required); + } -template <typename T, typename E> -template <typename M, typename F> -cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind( - const cm::string_view& name, std::nullptr_t, F func, bool required) -{ - return this->BindPrivate(name, - [func](T& /*out*/, const Json::Value* value) -> E { - M dummy; - return func(dummy, value); - }, - required); -} + E operator()(T& out, const Json::Value* value) const + { + if (!value && this->AnyRequired) { + return this->Fail; + } + if (value && !value->isObject()) { + return this->Fail; + } + Json::Value::Members extraFields; + if (value) { + extraFields = value->getMemberNames(); + } -template <typename T, typename E> -template <typename F> -cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind( - const cm::string_view& name, F func, bool required) -{ - return this->BindPrivate(name, MemberFunction(func), required); -} + for (auto const& m : this->Members) { + std::string name(m.Name.data(), m.Name.size()); + if (value && value->isMember(name)) { + E result = m.Function(out, &(*value)[name]); + if (result != this->Success) { + return result; + } + extraFields.erase( + std::find(extraFields.begin(), extraFields.end(), name)); + } else if (!m.Required) { + E result = m.Function(out, nullptr); + if (result != this->Success) { + return result; + } + } else { + return this->Fail; + } + } -template <typename T, typename E> -cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::BindPrivate( - const cm::string_view& name, MemberFunction&& func, bool required) -{ - Member m; - m.Name = name; - m.Function = std::move(func); - m.Required = required; - this->Members.push_back(std::move(m)); - if (required) { - this->AnyRequired = true; - } - return *this; -} + return this->AllowExtra || extraFields.empty() ? this->Success + : this->Fail; + } -template <typename T, typename E> -E cmJSONObjectHelper<T, E>::operator()(T& out, const Json::Value* value) const -{ - if (!value && this->AnyRequired) { - return this->Fail; - } - if (value && !value->isObject()) { - return this->Fail; - } - Json::Value::Members extraFields; - if (value) { - extraFields = value->getMemberNames(); - } + private: + // Not a true cmJSONHelper, it just happens to match the signature + using MemberFunction = std::function<E(T& out, const Json::Value* value)>; + struct Member + { + cm::string_view Name; + MemberFunction Function; + bool Required; + }; + std::vector<Member> Members; + bool AnyRequired = false; + E Success; + E Fail; + bool AllowExtra; - for (auto const& m : this->Members) { - std::string name(m.Name.data(), m.Name.size()); - if (value && value->isMember(name)) { - E result = m.Function(out, &(*value)[name]); - if (result != this->Success) { - return result; + Object& BindPrivate(const cm::string_view& name, MemberFunction&& func, + bool required) + { + Member m; + m.Name = name; + m.Function = std::move(func); + m.Required = required; + this->Members.push_back(std::move(m)); + if (required) { + this->AnyRequired = true; } - extraFields.erase( - std::find(extraFields.begin(), extraFields.end(), name)); - } else if (!m.Required) { - E result = m.Function(out, nullptr); - if (result != this->Success) { - return result; - } - } else { - return this->Fail; + return *this; } - } - - return this->AllowExtra || extraFields.empty() ? this->Success : this->Fail; -} - -template <typename E> -cmJSONHelper<std::string, E> cmJSONStringHelper(E success, E fail, - const std::string& defval = "") -{ - return - [success, fail, defval](std::string& out, const Json::Value* value) -> E { + }; + static cmJSONHelper<std::string, E> String(E success, E fail, + const std::string& defval = "") + { + return [success, fail, defval](std::string& out, + const Json::Value* value) -> E { if (!value) { out = defval; return success; @@ -164,30 +140,28 @@ cmJSONHelper<std::string, E> cmJSONStringHelper(E success, E fail, out = value->asString(); return success; }; -} + } -template <typename E> -cmJSONHelper<int, E> cmJSONIntHelper(E success, E fail, int defval = 0) -{ - return [success, fail, defval](int& out, const Json::Value* value) -> E { - if (!value) { - out = defval; + static cmJSONHelper<int, E> Int(E success, E fail, int defval = 0) + { + return [success, fail, defval](int& out, const Json::Value* value) -> E { + if (!value) { + out = defval; + return success; + } + if (!value->isInt()) { + return fail; + } + out = value->asInt(); return success; - } - if (!value->isInt()) { - return fail; - } - out = value->asInt(); - return success; - }; -} + }; + } -template <typename E> -cmJSONHelper<unsigned int, E> cmJSONUIntHelper(E success, E fail, - unsigned int defval = 0) -{ - return - [success, fail, defval](unsigned int& out, const Json::Value* value) -> E { + static cmJSONHelper<unsigned int, E> UInt(E success, E fail, + unsigned int defval = 0) + { + return [success, fail, defval](unsigned int& out, + const Json::Value* value) -> E { if (!value) { out = defval; return success; @@ -198,118 +172,119 @@ cmJSONHelper<unsigned int, E> cmJSONUIntHelper(E success, E fail, out = value->asUInt(); return success; }; -} + } -template <typename E> -cmJSONHelper<bool, E> cmJSONBoolHelper(E success, E fail, bool defval = false) -{ - return [success, fail, defval](bool& out, const Json::Value* value) -> E { - if (!value) { - out = defval; + static cmJSONHelper<bool, E> Bool(E success, E fail, bool defval = false) + { + return [success, fail, defval](bool& out, const Json::Value* value) -> E { + if (!value) { + out = defval; + return success; + } + if (!value->isBool()) { + return fail; + } + out = value->asBool(); return success; - } - if (!value->isBool()) { - return fail; - } - out = value->asBool(); - return success; - }; -} + }; + } -template <typename T, typename E, typename F, typename Filter> -cmJSONHelper<std::vector<T>, E> cmJSONVectorFilterHelper(E success, E fail, - F func, Filter filter) -{ - return [success, fail, func, filter](std::vector<T>& out, - const Json::Value* value) -> E { - if (!value) { - out.clear(); - return success; - } - if (!value->isArray()) { - return fail; - } - out.clear(); - for (auto const& item : *value) { - T t; - E result = func(t, &item); - if (result != success) { - return result; + template <typename T, typename F, typename Filter> + static cmJSONHelper<std::vector<T>, E> VectorFilter(E success, E fail, + F func, Filter filter) + { + return [success, fail, func, filter](std::vector<T>& out, + const Json::Value* value) -> E { + if (!value) { + out.clear(); + return success; } - if (!filter(t)) { - continue; + if (!value->isArray()) { + return fail; } - out.push_back(std::move(t)); - } - return success; - }; -} - -template <typename T, typename E, typename F> -cmJSONHelper<std::vector<T>, E> cmJSONVectorHelper(E success, E fail, F func) -{ - return cmJSONVectorFilterHelper<T, E, F>(success, fail, func, - [](const T&) { return true; }); -} - -template <typename T, typename E, typename F, typename Filter> -cmJSONHelper<std::map<std::string, T>, E> cmJSONMapFilterHelper(E success, - E fail, F func, - Filter filter) -{ - return [success, fail, func, filter](std::map<std::string, T>& out, - const Json::Value* value) -> E { - if (!value) { out.clear(); + for (auto const& item : *value) { + T t; + E result = func(t, &item); + if (result != success) { + return result; + } + if (!filter(t)) { + continue; + } + out.push_back(std::move(t)); + } return success; - } - if (!value->isObject()) { - return fail; - } - out.clear(); - for (auto const& key : value->getMemberNames()) { - if (!filter(key)) { - continue; + }; + } + + template <typename T, typename F> + static cmJSONHelper<std::vector<T>, E> Vector(E success, E fail, F func) + { + return VectorFilter<T, F>(success, fail, func, + [](const T&) { return true; }); + } + + template <typename T, typename F, typename Filter> + static cmJSONHelper<std::map<std::string, T>, E> MapFilter(E success, E fail, + F func, + Filter filter) + { + return [success, fail, func, filter](std::map<std::string, T>& out, + const Json::Value* value) -> E { + if (!value) { + out.clear(); + return success; } - T t; - E result = func(t, &(*value)[key]); - if (result != success) { - return result; + if (!value->isObject()) { + return fail; } - out[key] = std::move(t); - } - return success; - }; -} + out.clear(); + for (auto const& key : value->getMemberNames()) { + if (!filter(key)) { + continue; + } + T t; + E result = func(t, &(*value)[key]); + if (result != success) { + return result; + } + out[key] = std::move(t); + } + return success; + }; + } -template <typename T, typename E, typename F> -cmJSONHelper<std::map<std::string, T>, E> cmJSONMapHelper(E success, E fail, - F func) -{ - return cmJSONMapFilterHelper<T, E, F>( - success, fail, func, [](const std::string&) { return true; }); -} + template <typename T, typename F> + static cmJSONHelper<std::map<std::string, T>, E> Map(E success, E fail, + F func) + { + return MapFilter<T, F>(success, fail, func, + [](const std::string&) { return true; }); + } -template <typename T, typename E, typename F> -cmJSONHelper<cm::optional<T>, E> cmJSONOptionalHelper(E success, F func) -{ - return [success, func](cm::optional<T>& out, const Json::Value* value) -> E { - if (!value) { - out.reset(); - return success; - } - out.emplace(); - return func(*out, value); - }; -} + template <typename T, typename F> + static cmJSONHelper<cm::optional<T>, E> Optional(E success, F func) + { + return + [success, func](cm::optional<T>& out, const Json::Value* value) -> E { + if (!value) { + out.reset(); + return success; + } + out.emplace(); + return func(*out, value); + }; + } -template <typename T, typename E, typename F> -cmJSONHelper<T, E> cmJSONRequiredHelper(E fail, F func) -{ - return [fail, func](T& out, const Json::Value* value) -> E { - if (!value) { - return fail; - } - return func(out, value); - }; -} + template <typename T, typename F> + static cmJSONHelper<T, E> Required(E fail, F func) + { + return [fail, func](T& out, const Json::Value* value) -> E { + if (!value) { + return fail; + } + return func(out, value); + }; + } +}; diff --git a/Tests/CMakeLib/testJSONHelpers.cxx b/Tests/CMakeLib/testJSONHelpers.cxx index a45d3205c5..2cd3f75160 100644 --- a/Tests/CMakeLib/testJSONHelpers.cxx +++ b/Tests/CMakeLib/testJSONHelpers.cxx @@ -43,32 +43,33 @@ enum class ErrorCode MissingRequired, }; +using JSONHelperBuilder = cmJSONHelperBuilder<ErrorCode>; + auto const IntHelper = - cmJSONIntHelper<ErrorCode>(ErrorCode::Success, ErrorCode::InvalidInt, 1); + JSONHelperBuilder::Int(ErrorCode::Success, ErrorCode::InvalidInt, 1); auto const RequiredIntHelper = - cmJSONRequiredHelper<int, ErrorCode>(ErrorCode::MissingRequired, IntHelper); + JSONHelperBuilder::Required<int>(ErrorCode::MissingRequired, IntHelper); auto const UIntHelper = - cmJSONUIntHelper<ErrorCode>(ErrorCode::Success, ErrorCode::InvalidInt, 1); -auto const BoolHelper = cmJSONBoolHelper<ErrorCode>( - ErrorCode::Success, ErrorCode::InvalidBool, false); -auto const StringHelper = cmJSONStringHelper<ErrorCode>( + JSONHelperBuilder::UInt(ErrorCode::Success, ErrorCode::InvalidInt, 1); +auto const BoolHelper = + JSONHelperBuilder::Bool(ErrorCode::Success, ErrorCode::InvalidBool, false); +auto const StringHelper = JSONHelperBuilder::String( ErrorCode::Success, ErrorCode::InvalidString, "default"); -auto const RequiredStringHelper = cmJSONRequiredHelper<std::string, ErrorCode>( +auto const RequiredStringHelper = JSONHelperBuilder::Required<std::string>( ErrorCode::MissingRequired, StringHelper); -auto const StringVectorHelper = cmJSONVectorHelper<std::string, ErrorCode>( +auto const StringVectorHelper = JSONHelperBuilder::Vector<std::string>( ErrorCode::Success, ErrorCode::InvalidArray, StringHelper); auto const StringVectorFilterHelper = - cmJSONVectorFilterHelper<std::string, ErrorCode>( + JSONHelperBuilder::VectorFilter<std::string>( ErrorCode::Success, ErrorCode::InvalidArray, StringHelper, [](const std::string& value) { return value != "ignore"; }); -auto const StringMapHelper = cmJSONMapHelper<std::string, ErrorCode>( +auto const StringMapHelper = JSONHelperBuilder::Map<std::string>( ErrorCode::Success, ErrorCode::InvalidObject, StringHelper); -auto const StringMapFilterHelper = - cmJSONMapFilterHelper<std::string, ErrorCode>( - ErrorCode::Success, ErrorCode::InvalidObject, StringHelper, - [](const std::string& key) { return key != "ignore"; }); +auto const StringMapFilterHelper = JSONHelperBuilder::MapFilter<std::string>( + ErrorCode::Success, ErrorCode::InvalidObject, StringHelper, + [](const std::string& key) { return key != "ignore"; }); auto const OptionalStringHelper = - cmJSONOptionalHelper<std::string>(ErrorCode::Success, StringHelper); + JSONHelperBuilder::Optional<std::string>(ErrorCode::Success, StringHelper); bool testInt() { @@ -150,10 +151,10 @@ bool testString() bool testObject() { auto const subhelper = - cmJSONObjectHelper<ObjectStruct, ErrorCode>(ErrorCode::Success, - ErrorCode::InvalidSubObject) + JSONHelperBuilder::Object<ObjectStruct>(ErrorCode::Success, + ErrorCode::InvalidSubObject) .Bind("subfield"_s, &ObjectStruct::Field2, IntHelper); - auto const helper = cmJSONObjectHelper<ObjectStruct, ErrorCode>( + auto const helper = JSONHelperBuilder::Object<ObjectStruct>( ErrorCode::Success, ErrorCode::InvalidObject) .Bind("field1"_s, &ObjectStruct::Field1, StringHelper) .Bind("field2"_s, subhelper) @@ -206,8 +207,8 @@ bool testObject() bool testObjectInherited() { auto const helper = - cmJSONObjectHelper<InheritedStruct, ErrorCode>(ErrorCode::Success, - ErrorCode::InvalidObject) + JSONHelperBuilder::Object<InheritedStruct>(ErrorCode::Success, + ErrorCode::InvalidObject) .Bind("field1"_s, &InheritedStruct::Field1, StringHelper) .Bind("field2"_s, &InheritedStruct::Field2, IntHelper) .Bind("field3"_s, &InheritedStruct::Field3, StringHelper); @@ -253,7 +254,7 @@ bool testObjectInherited() bool testObjectNoExtra() { - auto const helper = cmJSONObjectHelper<ObjectStruct, ErrorCode>( + auto const helper = JSONHelperBuilder::Object<ObjectStruct>( ErrorCode::Success, ErrorCode::InvalidObject, false) .Bind("field1"_s, &ObjectStruct::Field1, StringHelper) .Bind("field2"_s, &ObjectStruct::Field2, IntHelper); @@ -277,8 +278,8 @@ bool testObjectNoExtra() bool testObjectOptional() { auto const helper = - cmJSONObjectHelper<ObjectStruct, ErrorCode>(ErrorCode::Success, - ErrorCode::InvalidObject) + JSONHelperBuilder::Object<ObjectStruct>(ErrorCode::Success, + ErrorCode::InvalidObject) .Bind("field1"_s, &ObjectStruct::Field1, StringHelper, false) .Bind("field2"_s, &ObjectStruct::Field2, IntHelper, false) .Bind<std::string>("field3_s", nullptr, StringHelper, false); |