#pragma once #include #include #include #include #include #include #include #include "src/Services/StringService.hpp" #include "src/Exceptions/Exception.hpp" namespace Targets::TargetDescription { struct Property { std::string key; std::string value; Property(const std::string& key, const std::string& value) : key(key) , value(value) {} }; struct PropertyGroup { std::string key; std::map> propertiesByKey; std::map> subgroupByKey; PropertyGroup( const std::string& key, const std::map>& propertiesByKey, const std::map>& subgroupByKey ) : key(key) , propertiesByKey(propertiesByKey) , subgroupByKey(subgroupByKey) {} template requires std::ranges::sized_range std::optional> tryGetSubgroup(KeysType keys) const { auto firstSubgroupIt = this->subgroupByKey.find(*(keys.begin())); if (firstSubgroupIt == this->subgroupByKey.end()) { return std::nullopt; } auto subgroup = std::optional(std::cref(firstSubgroupIt->second)); for (const auto key : keys | std::ranges::views::drop(1)) { subgroup = subgroup->get().tryGetSubgroup(key); if (!subgroup.has_value()) { break; } } return subgroup; } std::optional> tryGetSubgroup(std::string_view keyStr) const { return this->tryGetSubgroup(Services::StringService::split(keyStr, '.')); } std::optional> 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> tryGetProperty(std::string_view key) const { const auto propertyIt = this->propertiesByKey.find(key); 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(); } }; }