Files
ros2-assignments/src/g2_2025_imu_reader_pkg/src/config/ConfigManager.cpp

113 lines
3.7 KiB
C++

#include "ConfigManager.hpp"
#include <iostream>
#include <fstream>
namespace assignments::two {
ConfigManager::ConfigManager(rclcpp::Logger logger)
: logger_(logger), loaded_(false)
{
// Try to auto-load config from default location
std::string config_path = find_config_file();
if (!config_path.empty()) {
load_config(config_path);
}
}
bool ConfigManager::load_config(const std::string& config_file_path) {
try {
RCLCPP_INFO(logger_, "[CFG] '%s': loading configuration", config_file_path.c_str());
if (!std::filesystem::exists(config_file_path)) {
RCLCPP_ERROR(logger_, "[CFG] '%s': file does not exist", config_file_path.c_str());
return false;
}
config_ = toml::parse_file(config_file_path);
loaded_ = true;
RCLCPP_INFO(logger_, "[CFG] '%s': configuration loaded", config_file_path.c_str());
return true;
} catch (const toml::parse_error& e) {
RCLCPP_ERROR(logger_, "[CFG] '%s': failed to parse: %s", config_file_path.c_str(), e.what());
loaded_ = false;
return false;
} catch (const std::exception& e) {
RCLCPP_ERROR(logger_, "[CFG] '%s': failed to load: %s", config_file_path.c_str(), e.what());
loaded_ = false;
return false;
}
}
std::optional<DatabaseConfig> ConfigManager::get_database_config() const {
if (!loaded_ || !config_.has_value()) {
RCLCPP_ERROR(logger_, "[CFG] database configuration not loaded");
return std::nullopt;
}
try {
return parse_database_config(config_.value());
} catch (const std::exception& e) {
RCLCPP_ERROR(logger_, "[CFG] database configuration failed to parse: %s", e.what());
return std::nullopt;
}
}
bool ConfigManager::is_loaded() const {
return loaded_;
}
std::string ConfigManager::find_config_file() const {
// Look for config file in several locations
for (const auto& path : default_config_paths_) {
if (std::filesystem::exists(path)) {
RCLCPP_INFO(logger_, "[CFG] '%s': found configuration file", path.c_str());
return path;
}
}
RCLCPP_WARN(logger_, "[CFG] no configuration file found at default locations");
return "";
}
DatabaseConfig ConfigManager::parse_database_config(const toml::table& config) const {
DatabaseConfig db_config;
// Parse database section
auto database_section = config["database"];
if (!database_section) {
throw std::runtime_error("missing [database] section in configuration");
}
db_config.host = database_section["host"].value_or<std::string>("localhost");
db_config.port = database_section["port"].value_or<int>(5432);
db_config.dbname = database_section["dbname"].value_or<std::string>("grades");
db_config.user = database_section["user"].value_or<std::string>("postgres");
db_config.password = database_section["password"].value_or<std::string>("postgres");
db_config.timeout = database_section["timeout"].value_or<int>(30);
db_config.ssl = database_section["ssl"].value_or<bool>(false);
// Parse pool section if present
auto pool_section = database_section["pool"];
if (pool_section) {
db_config.min_connections = pool_section["min_connections"].value_or<int>(1);
db_config.max_connections = pool_section["max_connections"].value_or<int>(10);
} else {
db_config.min_connections = 1;
db_config.max_connections = 10;
}
RCLCPP_INFO(logger_, "[CFG] database config parsed - %s:%s@%s:%d",
db_config.user.c_str(),
db_config.dbname.c_str(),
db_config.host.c_str(),
db_config.port
);
return db_config;
}
} // namespace assignments::two