.. _program_listing_file_src_utils_TOMLUtils.hpp: Program Listing for File TOMLUtils.hpp ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/utils/TOMLUtils.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef TOMLUTILS_HPP #define TOMLUTILS_HPP #include "../pdfs/PDF.hpp" #include "../pdfs/PDFFileParser.hpp" #include "../pdfs/PDFSegmentDelta.hpp" #include "MiscUtils.hpp" #include #include #include #include #include #include #include #include #include #include namespace utils { inline auto stringArrayContents(const toml::array* arr) -> std::vector { std::vector result; if (arr != nullptr) { arr->for_each([&result](auto&& el) -> void { if constexpr (toml::is_string) { result.push_back(std::string(el)); } }); } return result; } inline auto getStringArrayField(const toml::table& registry, const std::string& key) -> std::vector { return stringArrayContents(registry.at_path(key).as_array()); } inline auto initPDFFromKey(const toml::table& inputDeck, const std::string& key, const std::string& prefix = "") -> pdfs::PDF { // First check for numerical value const std::optional num = inputDeck.at_path(key).value(); if (num.has_value()) { auto delta = std::make_unique(num.value()); auto pdf = pdfs::PDF(std::move(delta)); return std::move(pdf); } // Next check for string value const std::optional pdfFile = inputDeck.at_path(key).value(); if (pdfFile.has_value()) { auto pdfFilePath = getFilePath(pdfFile.value(), prefix).string(); if (pdfFilePath.empty()) { throw std::runtime_error( "initPDFFromKey: pdf file " + pdfFile.value() + " not found"); } auto pdf = pdfs::parsePDFDescriptor(pdfFilePath); return std::move(pdf); } // If we get here, key does not exist or has invalid type throw std::runtime_error( "initPDFFromKey: invalid entry for " + key); } inline auto parseTOMLFile(const std::string& fileName, const std::string& context) -> std::pair { auto path = getFilePath(fileName); if (path.empty()) { throw std::runtime_error( context + ": registry " + fileName + " not found"); } toml::table table; try { table = toml::parse_file(path.string()); } catch (const std::exception&) { throw std::runtime_error( context + ": registry " + path.string() + " is not a valid toml file"); } return { std::move(table), std::move(path) }; } inline auto parseSetRegistry( const std::string& registryName, const std::string& setsKey, const std::string& itemNoun, const std::string& context, const bool requireFeH = true) -> std::tuple> { auto [registry, registryPath] = parseTOMLFile(registryName, context); auto sets = getStringArrayField(registry, setsKey); if (sets.empty()) { throw std::runtime_error( context + ": registry " + registryPath.string() + " does not contain a valid [" + setsKey + "] field"); } for (const auto& s : sets) { if (!registry.contains(s)) { std::string msg = context + ": registry " + registryPath.string(); msg += " is missing entry for "; msg += itemNoun; msg += " "; msg += s; throw std::runtime_error(msg); } const auto entry = registry.at_path(s); if (!entry.at_path("file") || (requireFeH && !entry.at_path("Fe_H"))) { std::string msg = context + ": registry " + registryPath.string(); msg += ", entry for "; msg += itemNoun; msg += " "; msg += s; msg += requireFeH ? " is missing required 'file' or 'Fe_H' fields" : " is missing required 'file' field"; throw std::runtime_error(msg); } } return { std::move(registry), std::move(registryPath), std::move(sets) }; } } // namespace utils #endif // TOMLUTILS_HPP