Program Listing for File yaml_utils.hpp
↰ Return to documentation for file (include/as2_core/utils/yaml_utils.hpp
)
// Copyright 2023 Universidad Politécnica de Madrid
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the Universidad Politécnica de Madrid nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/********************************************************************************************
* \file yaml_utils.hpp
* \brief Utils for loading YAML files in Aerostack2.
* \authors Miguel Fernández Cortizas
********************************************************************************/
#ifndef AS2_CORE__UTILS__YAML_UTILS_HPP_
#define AS2_CORE__UTILS__YAML_UTILS_HPP_
#include <yaml-cpp/yaml.h>
#include <bitset>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
namespace as2
{
namespace yaml
{
std::filesystem::path get_project_export_path_from_xml_path(const std::filesystem::path & xml_path);
std::vector<std::filesystem::path> find_yaml_files_inside(const std::filesystem::path & dir);
YAML::Node find_tag_across_multiple_yaml_files(
const std::vector<std::filesystem::path> & yaml_files, const std::string & tag);
uint8_t parse_uint_from_string(const std::string & str);
std::vector<uint8_t> parse_uint_from_string(const std::vector<std::string> & str_v);
// Recursive function to find the tag inside the yaml file
YAML::Node find_tag_in_yaml_node(const YAML::Node & node, const std::string & tag);
template<typename T = std::string>
std::vector<T> find_tag_in_yaml_file(
const std::filesystem::path & yaml_file, const std::string & tag)
{
std::vector<T> result;
std::ifstream config_file(yaml_file);
// check if file exists
if (!config_file.good()) {
throw std::runtime_error("Could not open yaml file: " + yaml_file.string());
}
YAML::Node node = YAML::LoadFile(yaml_file.string());
if (!node.IsNull()) {
YAML::Node tag_node = find_tag_in_yaml_node(node, tag);
if (!tag_node.IsNull()) {
// for (const auto & tag_value : tag_node) {
// result.push_back(tag_value.as<T>()); }
// done it with std::transform ->
std::transform(
tag_node.begin(), tag_node.end(), std::back_inserter(result),
[](const YAML::Node & node) {return node.as<T>();});
}
} else {
throw std::runtime_error("Could not parse yaml file: " + yaml_file.string());
}
return result;
}
template<typename T = std::string>
std::vector<T> find_tag_from_project_exports_path(
const std::filesystem::path & project_exports_path, const std::string & tag)
{
std::vector<T> values;
std::vector<std::filesystem::path> yaml_files = find_yaml_files_inside(project_exports_path);
if (yaml_files.size() == 0) {
throw std::runtime_error("Could not find any yaml files in: " + project_exports_path.string());
}
for (const auto & yaml_file : yaml_files) {
auto tags = find_tag_in_yaml_file<T>(yaml_file, tag);
if (tags.size() > 0) {
values = tags;
}
}
return values;
}
} // namespace yaml
} // namespace as2
#endif // AS2_CORE__UTILS__YAML_UTILS_HPP_