#ifndef LIBREPOMGR_HELPER_H #define LIBREPOMGR_HELPER_H #include #include #include #include #include #include #include #include #include #include #include namespace LibRepoMgr { namespace Traits = CppUtilities::Traits; inline const char *getLastValue(const std::multimap &multimap, const std::string &key) { using namespace std; const auto it = find_if(multimap.crbegin(), multimap.crend(), [&key](const pair &i) { return i.first == key; }); if (it != multimap.rend()) { return it->second.data(); } return nullptr; } inline std::optional getLastValueSv(const std::multimap &multimap, const std::string &key) { using namespace std; const auto it = find_if(multimap.crbegin(), multimap.crend(), [&key](const pair &i) { return i.first == key; }); if (it != multimap.rend()) { return it->second.data(); } return std::nullopt; } template > * = nullptr> void convertValue(const std::multimap &multimap, const std::string &key, TargetType &result); template <> inline void convertValue(const std::multimap &multimap, const std::string &key, boost::asio::ip::address &result) { using namespace std; using namespace CppUtilities::EscapeCodes; if (const char *const value = getLastValue(multimap, key)) { boost::system::error_code error; const auto ip = boost::asio::ip::make_address(value, error); if (error) { cerr << Phrases::ErrorMessage << "Specified IP address \"" << value << "\" for key \"" << key << "\" is invalid" << Phrases::End << Phrases::SubError << error.message() << Phrases::End; return; } result = ip; } } template > * = nullptr> inline void convertValue(const std::multimap &multimap, const std::string &key, TargetType &result) { using namespace std; using namespace CppUtilities; using namespace CppUtilities::EscapeCodes; if (const char *const value = getLastValue(multimap, key)) { try { result = stringToNumber(value); } catch (const ConversionException &) { cerr << Phrases::ErrorMessage << "Specified number \"" << value << "\" for key \"" << key << "\" is invalid." << Phrases::End; return; } } } template <> inline void convertValue(const std::multimap &multimap, const std::string &key, std::string &result) { if (const char *const value = getLastValue(multimap, key)) { result = value; } } template <> inline void convertValue(const std::multimap &multimap, const std::string &key, std::regex &result) { using namespace std; using namespace CppUtilities::EscapeCodes; if (const char *const value = getLastValue(multimap, key)) { try { result = value; } catch (const regex_error &e) { cerr << Phrases::ErrorMessage << "Specified regex \"" << value << "\" for key \"" << key << "\" is invalid: " << Phrases::End; cerr << e.what() << '\n'; return; } } } template <> inline void convertValue(const std::multimap &multimap, const std::string &key, std::vector &result) { for (auto range = multimap.equal_range(key); range.first != range.second; ++range.first) { result.emplace_back(range.first->second); } } template <> inline void convertValue(const std::multimap &multimap, const std::string &key, bool &result) { if (const char *const value = getLastValue(multimap, key)) { result = !strcmp(value, "on") || !strcmp(value, "yes"); } } template void mergeSecondVectorIntoFirstVector(VectorType &firstVector, VectorType &secondVector) { const auto requiredSize = firstVector.size() + secondVector.size(); if (firstVector.capacity() < requiredSize) { firstVector.reserve(requiredSize); } for (auto &i : secondVector) { firstVector.emplace_back(std::move(i)); } secondVector.clear(); } template void copySecondVectorIntoFirstVector(VectorType &firstVector, const VectorType &secondVector) { const auto requiredSize = firstVector.size() + secondVector.size(); if (firstVector.capacity() < requiredSize) { firstVector.reserve(requiredSize); } for (auto &i : secondVector) { firstVector.emplace_back(i); } } template auto map(const Objects &objects, Accessor accessor) { ListType things; things.reserve(objects.size()); for (const auto &object : objects) { things.emplace_back(accessor(object)); } return things; } template auto names(const Objects &objects) { return map(objects, [](const auto &object) { return Traits::dereferenceMaybe(object).name; }); } } // namespace LibRepoMgr #endif // LIBREPOMGR_HELPER_H