From dc1a0500e763dc6087a6d319b1a551d34471ef08 Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Wed, 9 Aug 2023 13:44:39 +0100 Subject: [PATCH] Put configuration parsing helper function defs into own header This is so we can test them with GTest. --- src/HealthGPS.Console/CMakeLists.txt | 1 + .../configuration_parsing.cpp | 57 ++---------- .../configuration_parsing_helpers.h | 87 +++++++++++++++++++ 3 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 src/HealthGPS.Console/configuration_parsing_helpers.h diff --git a/src/HealthGPS.Console/CMakeLists.txt b/src/HealthGPS.Console/CMakeLists.txt index ffe2027e8..787c424ff 100644 --- a/src/HealthGPS.Console/CMakeLists.txt +++ b/src/HealthGPS.Console/CMakeLists.txt @@ -19,6 +19,7 @@ target_sources(HealthGPS.Console "configuration.h" "configuration_parsing.cpp" "configuration_parsing.h" + "configuration_parsing_helpers.h" "csvparser.cpp" "csvparser.h" "event_monitor.cpp" diff --git a/src/HealthGPS.Console/configuration_parsing.cpp b/src/HealthGPS.Console/configuration_parsing.cpp index 1a36ff947..9361f62bc 100644 --- a/src/HealthGPS.Console/configuration_parsing.cpp +++ b/src/HealthGPS.Console/configuration_parsing.cpp @@ -1,4 +1,5 @@ #include "configuration_parsing.h" +#include "configuration_parsing_helpers.h" #include "jsonparser.h" #include @@ -8,12 +9,7 @@ namespace host { using json = nlohmann::json; -/// @brief Load value from JSON, printing an error message if it fails -/// @param j JSON object -/// @param key Key to value -/// @throw ConfigurationError: Key not found -/// @return Key value -auto get(const json &j, const std::string &key) { +nlohmann::json get(const json &j, const std::string &key) { try { return j.at(key); } catch (const std::out_of_range &) { @@ -22,12 +18,6 @@ auto get(const json &j, const std::string &key) { } } -/// @brief Get value from JSON object and store in out -/// @tparam T Type of output object -/// @param j JSON object -/// @param key Key to value -/// @param out Output object -/// @return True if value was retrieved successfully, false otherwise template bool get_to(const json &j, const std::string &key, T &out) { try { j.at(key).get_to(out); @@ -41,13 +31,6 @@ template bool get_to(const json &j, const std::string &key, T &out) { } } -/// @brief Get value from JSON object and store in out, setting success flag -/// @tparam T Type of output object -/// @param j JSON object -/// @param key Key to value -/// @param out Output object -/// @param success Success flag, set to false in case of failure -/// @return True if value was retrieved successfully, false otherwise template bool get_to(const json &j, const std::string &key, T &out, bool &success) { const bool ret = get_to(j, key, out); if (!ret) { @@ -56,10 +39,6 @@ template bool get_to(const json &j, const std::string &key, T &out, bo return ret; } -/// @brief Rebase path on base_dir -/// @param path Initial path (relative or absolute) -/// @param base_dir New base directory for relative path -/// @throw ConfigurationError: If path does not exist void rebase_valid_path(std::filesystem::path &path, const std::filesystem::path &base_dir) { if (path.is_relative()) { path = std::filesystem::weakly_canonical(base_dir / path); @@ -70,12 +49,6 @@ void rebase_valid_path(std::filesystem::path &path, const std::filesystem::path } } -/// @brief Get a valid path from a JSON object -/// @param j JSON object -/// @param key Key to value -/// @param base_dir Base directory for relative path -/// @param out Output variable -/// @return True if value was retrieved successfully and is valid path, false otherwise bool get_valid_path_to(const json &j, const std::string &key, const std::filesystem::path &base_dir, std::filesystem::path &out) { if (!get_to(j, key, out)) { @@ -92,12 +65,6 @@ bool get_valid_path_to(const json &j, const std::string &key, const std::filesys return true; } -/// @brief Get a valid path from a JSON object -/// @param j JSON object -/// @param key Key to value -/// @param base_dir Base directory for relative path -/// @param out Output variable -/// @param success Success flag, set to false in case of failure void get_valid_path_to(const json &j, const std::string &key, const std::filesystem::path &base_dir, std::filesystem::path &out, bool &success) { if (!get_valid_path_to(j, key, base_dir, out)) { @@ -105,12 +72,7 @@ void get_valid_path_to(const json &j, const std::string &key, const std::filesys } } -/// @brief Load FileInfo from JSON -/// @param j Input JSON -/// @param base_dir Base folder -/// @return FileInfo -/// @throw ConfigurationError: Invalid config file format -auto get_file_info(const json &j, const std::filesystem::path &base_dir) { +poco::FileInfo get_file_info(const json &j, const std::filesystem::path &base_dir) { const auto dataset = get(j, "dataset"); bool success = true; @@ -126,7 +88,7 @@ auto get_file_info(const json &j, const std::filesystem::path &base_dir) { return info; } -auto get_settings(const json &j) { +poco::SettingsInfo get_settings(const json &j) { poco::SettingsInfo info; if (!get_to(j, "settings", info)) { throw ConfigurationError{"Could not load settings info"}; @@ -135,12 +97,7 @@ auto get_settings(const json &j) { return info; } -/// @brief Load BaselineInfo from JSON -/// @param j Input JSON -/// @param base_dir Base folder -/// @return BaselineInfo -/// @throw ConfigurationError: One or more files could not be found -auto get_baseline_info(const json &j, const std::filesystem::path &base_dir) { +poco::BaselineInfo get_baseline_info(const json &j, const std::filesystem::path &base_dir) { const auto &adj = get(j, "baseline_adjustments"); bool success = true; @@ -168,10 +125,6 @@ auto get_baseline_info(const json &j, const std::filesystem::path &base_dir) { return info; } -/// @brief Load interventions from running section -/// @param running Running section of JSON object -/// @param config Config object to update -/// @throw ConfigurationError: Could not load interventions void load_interventions(const json &running, Configuration &config) { const auto interventions = get(running, "interventions"); diff --git a/src/HealthGPS.Console/configuration_parsing_helpers.h b/src/HealthGPS.Console/configuration_parsing_helpers.h new file mode 100644 index 000000000..59111d580 --- /dev/null +++ b/src/HealthGPS.Console/configuration_parsing_helpers.h @@ -0,0 +1,87 @@ +#pragma once +#include "configuration.h" +#include "poco.h" + +#include + +#include +#include + +namespace host { +/// @brief Load value from JSON, printing an error message if it fails +/// @param j JSON object +/// @param key Key to value +/// @throw ConfigurationError: Key not found +/// @return Key value +nlohmann::json get(const nlohmann::json &j, const std::string &key); + +/// @brief Get value from JSON object and store in out +/// @tparam T Type of output object +/// @param j JSON object +/// @param key Key to value +/// @param out Output object +/// @return True if value was retrieved successfully, false otherwise +template bool get_to(const nlohmann::json &j, const std::string &key, T &out); + +/// @brief Get value from JSON object and store in out, setting success flag +/// @tparam T Type of output object +/// @param j JSON object +/// @param key Key to value +/// @param out Output object +/// @param success Success flag, set to false in case of failure +/// @return True if value was retrieved successfully, false otherwise +template +bool get_to(const nlohmann::json &j, const std::string &key, T &out, bool &success); + +/// @brief Rebase path on base_dir +/// @param path Initial path (relative or absolute) +/// @param base_dir New base directory for relative path +/// @throw ConfigurationError: If path does not exist +void rebase_valid_path(std::filesystem::path &path, const std::filesystem::path &base_dir); + +/// @brief Get a valid path from a JSON object +/// @param j JSON object +/// @param key Key to value +/// @param base_dir Base directory for relative path +/// @param out Output variable +/// @return True if value was retrieved successfully and is valid path, false otherwise +bool get_valid_path_to(const nlohmann::json &j, const std::string &key, + const std::filesystem::path &base_dir, std::filesystem::path &out); + +/// @brief Get a valid path from a JSON object +/// @param j JSON object +/// @param key Key to value +/// @param base_dir Base directory for relative path +/// @param out Output variable +/// @param success Success flag, set to false in case of failure +void get_valid_path_to(const nlohmann::json &j, const std::string &key, + const std::filesystem::path &base_dir, std::filesystem::path &out, + bool &success); + +/// @brief Load FileInfo from JSON +/// @param j Input JSON +/// @param base_dir Base folder +/// @return FileInfo +/// @throw ConfigurationError: Invalid config file format +poco::FileInfo get_file_info(const nlohmann::json &j, const std::filesystem::path &base_dir); + +/// @brief Load settings section of JSON +/// @param j Input JSON +/// @return SettingsInfo +/// @throw ConfigurationError: Could not load settings +poco::SettingsInfo get_settings(const nlohmann::json &j); + +/// @brief Load BaselineInfo from JSON +/// @param j Input JSON +/// @param base_dir Base folder +/// @return BaselineInfo +/// @throw ConfigurationError: One or more files could not be found +poco::BaselineInfo get_baseline_info(const nlohmann::json &j, + const std::filesystem::path &base_dir); + +/// @brief Load interventions from running section +/// @param running Running section of JSON object +/// @param config Config object to update +/// @throw ConfigurationError: Could not load interventions +void load_interventions(const nlohmann::json &running, Configuration &config); +} // namespace host