Files
BloomPatched/src/Targets/TargetDescription/PropertyGroup.hpp

102 lines
3.2 KiB
C++
Raw Normal View History

2021-04-04 21:04:12 +01:00
#pragma once
#include <string>
#include <map>
#include <optional>
#include <string_view>
#include <ranges>
#include <concepts>
#include <functional>
#include "src/Services/StringService.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Targets::TargetDescription
2021-04-04 21:04:12 +01:00
{
struct Property
{
std::string key;
std::string value;
2021-04-04 21:04:12 +01:00
Property(const std::string& key, const std::string& value)
: key(key)
, value(value)
{}
2021-04-04 21:04:12 +01:00
};
struct PropertyGroup
{
std::string key;
2024-02-13 20:24:52 +00:00
std::map<std::string, Property, std::less<void>> propertiesByKey;
std::map<std::string, PropertyGroup, std::less<void>> subgroupByKey;
PropertyGroup(
const std::string& key,
2024-02-13 20:24:52 +00:00
const std::map<std::string, Property, std::less<void>>& propertiesByKey,
const std::map<std::string, PropertyGroup, std::less<void>>& subgroupByKey
)
: key(key)
2024-02-13 20:24:52 +00:00
, propertiesByKey(propertiesByKey)
, subgroupByKey(subgroupByKey)
{}
template <typename KeysType>
requires
std::ranges::sized_range<KeysType>
2024-02-12 19:39:21 +00:00
std::optional<std::reference_wrapper<const PropertyGroup>> tryGetSubgroup(KeysType keys) const {
2024-02-13 20:24:52 +00:00
auto firstSubgroupIt = this->subgroupByKey.find(*(keys.begin()));
if (firstSubgroupIt == this->subgroupByKey.end()) {
return std::nullopt;
}
2024-02-12 19:39:21 +00:00
auto subgroup = std::optional(std::cref(firstSubgroupIt->second));
for (const auto key : keys | std::ranges::views::drop(1)) {
2024-02-12 19:39:21 +00:00
subgroup = subgroup->get().tryGetSubgroup(key);
2024-02-12 19:39:21 +00:00
if (!subgroup.has_value()) {
break;
}
}
2024-02-12 19:39:21 +00:00
return subgroup;
}
2024-02-12 19:39:21 +00:00
std::optional<std::reference_wrapper<const PropertyGroup>> tryGetSubgroup(std::string_view keyStr) const {
return this->tryGetSubgroup(Services::StringService::split(keyStr, '.'));
}
2024-02-12 19:39:21 +00:00
std::optional<std::reference_wrapper<const PropertyGroup>> getSubgroup(std::string_view keyStr) const {
const auto propertyGroup = this->tryGetSubgroup(keyStr);
if (!propertyGroup.has_value()) {
throw Exceptions::Exception(
"Failed to get subgroup \"" + std::string(keyStr)
+ "\" from property group in TDF - subgroup not found"
);
}
return propertyGroup->get();
}
std::optional<std::reference_wrapper<const Property>> tryGetProperty(std::string_view key) const {
2024-02-13 20:24:52 +00:00
const auto propertyIt = this->propertiesByKey.find(key);
2024-02-13 20:24:52 +00:00
if (propertyIt == this->propertiesByKey.end()) {
return std::nullopt;
}
return std::cref(propertyIt->second);
}
const Property& getProperty(std::string_view key) const {
const auto property = this->tryGetProperty(key);
if (!property.has_value()) {
throw Exceptions::Exception(
"Failed to get property \"" + std::string(key) + "\" from property group in TDF - property not found"
);
}
return property->get();
}
2021-04-04 21:04:12 +01:00
};
}