src/iguana/services/YAMLReader.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <optional> | ||
| 4 | #include <variant> | ||
| 5 | #include <vector> | ||
| 6 | |||
| 7 | #include <yaml-cpp/yaml.h> | ||
| 8 | |||
| 9 | #include "ConfigFileReader.h" | ||
| 10 | |||
| 11 | namespace iguana { | ||
| 12 | |||
| 13 | /// @brief A YAMLReader based on yaml-cpp | ||
| 14 | class YAMLReader : public ConfigFileReader | ||
| 15 | { | ||
| 16 | |||
| 17 | public: | ||
| 18 | |||
| 19 | /// A function `f : Node A -> Node B` which searches `YAML::Node A` for a specific `YAML::Node B`, returning it | ||
| 20 | using node_finder_t = std::function<YAML::Node(YAML::Node const)>; | ||
| 21 | |||
| 22 | /// Variant for identifying a `YAML::Node`: | ||
| 23 | /// - `std::string`: the key name of the node | ||
| 24 | /// - `node_finder_t`: how to find the node | ||
| 25 | using node_id_t = std::variant<std::string, node_finder_t>; | ||
| 26 | |||
| 27 | /// Representation of a path of `YAML::Node`s in a `YAML::Node` tree, _e.g._, in a YAML file. | ||
| 28 | using node_path_t = std::deque<node_id_t>; | ||
| 29 | |||
| 30 | /// @param name of this reader (for `Logger`) | ||
| 31 | 104 | YAMLReader(std::string_view name = "config") | |
| 32 | 104 | : ConfigFileReader(name) | |
| 33 | 104 | {} | |
| 34 | 104 | ~YAMLReader() {} | |
| 35 | |||
| 36 | /// Parse the YAML files added by `ConfigFileReader::AddFile` | ||
| 37 | void LoadFiles(); | ||
| 38 | |||
| 39 | /// @brief Convert a `YAML::Node` path to a string | ||
| 40 | /// | ||
| 41 | /// - elements are delimited by forward slashes (`/`) | ||
| 42 | /// - string elements are included | ||
| 43 | /// - `node_finder_t` elements are _not_ included | ||
| 44 | /// @param node_path the `YAML::Node` path | ||
| 45 | /// @return the converted string | ||
| 46 | static std::string NodePath2String(node_path_t const& node_path); | ||
| 47 | |||
| 48 | /// @brief Read a scalar value from a `YAML::Node` | ||
| 49 | /// @param node the `YAML::Node` to read | ||
| 50 | /// @return the scalar, if found | ||
| 51 | template <typename SCALAR> | ||
| 52 | std::optional<SCALAR> GetScalar(YAML::Node node); | ||
| 53 | |||
| 54 | /// @brief Read a scalar value from a `YAML::Node` path; searches all currently loaded config files. | ||
| 55 | /// @param node_path the `YAML::Node` path | ||
| 56 | /// @return the scalar, if found | ||
| 57 | template <typename SCALAR> | ||
| 58 | std::optional<SCALAR> GetScalar(node_path_t node_path); | ||
| 59 | |||
| 60 | /// @brief Read a vector value from a `YAML::Node` | ||
| 61 | /// @param node the `YAML::Node` to read | ||
| 62 | /// @return the vector, if found | ||
| 63 | template <typename SCALAR> | ||
| 64 | std::optional<std::vector<SCALAR>> GetVector(YAML::Node node); | ||
| 65 | |||
| 66 | /// @brief Read a vector value from a `YAML::Node` path; searches all currently loaded config files. | ||
| 67 | /// @param node_path the `YAML::Node` path | ||
| 68 | /// @return the vector, if found | ||
| 69 | template <typename SCALAR> | ||
| 70 | std::optional<std::vector<SCALAR>> GetVector(node_path_t node_path); | ||
| 71 | |||
| 72 | /// @brief Create a function to search a `YAML::Node` for a sub-`YAML::Node` such that the scalar `val` is within a range specified by `key` | ||
| 73 | /// @param key the key of the sub-`YAML::Node` to use as the range (its value must be a 2-vector) | ||
| 74 | /// @param val the scalar value to check | ||
| 75 | /// @returns the search function | ||
| 76 | template <typename SCALAR> | ||
| 77 | node_finder_t InRange(std::string const& key, SCALAR val); | ||
| 78 | |||
| 79 | private: | ||
| 80 | |||
| 81 | /// @brief Search a tree of `YAML::Node`s for a node specified by a `node_path_t` | ||
| 82 | /// @param node the root `YAML::Node` | ||
| 83 | /// @param node_path the path of `YAML::Node` identifiers | ||
| 84 | /// @returns either the found `YAML::Node`, or an empty (null) `YAML::Node` if one is not found | ||
| 85 | YAML::Node FindNode(YAML::Node node, node_path_t node_path); | ||
| 86 | |||
| 87 | /// Stack of `YAML::Node`s used to open files, together with their file names | ||
| 88 | std::deque<std::pair<YAML::Node, std::string>> m_configs; | ||
| 89 | }; | ||
| 90 | } | ||
| 91 |