# ConfigManager (`assignments::one::ConfigManager`) ## Overview The `ConfigManager` class is used to be able to store configuration values in a `TOML` file making it possible to change project settings without the need of recompiling the codebase. The [`toml++`](https://marzer.github.io/tomlplusplus/) library is used to parse TOML configuration files and provides type-safe access to configuration parameters. It is automatically installed using the `FetchContent_Declare` macro inside of the `CMakeLists.txt`. ## Implementation Details ### Dependencies - **toml++**: Modern header-only C++17 TOML parser and serializer - **rclcpp**: ROS2 C++ client library for logging - **filesystem**: C++17 filesystem library for file operations - **DatabaseConfig**: Custom data structure for database configuration ### Key Components #### Constructor ```cpp ConfigManager(rclcpp::Logger logger) ``` - Initializes the configuration manager making use of a ROS2 logger - Calls `find_config_file()` and `load_config()` for automatic setup - Automatically attempts to locate and load configuration from a list of pre-defined paths. #### Configuration Loading **`bool load_config(const std::string& config_file_path)`** > Returns `true` on successful load, `false` on failure - Uses `toml::parse_file()` - Loads TOML configuration from specified file path - Validates file existence before attempting to parse - Error handling for: - File not found errors - TOML parsing errors - General I/O exceptions - Updates internal `loaded_` state flag **`std::string find_config_file() const`** > Returns first found configuration file path > Returns empty string if no configuration file is found - Automatically searches for configuration files in predefined locations - Search paths (in order): ```cpp std::vector default_config_paths_ = { "config.toml", "./src/config.toml", "../config.toml", "../../config.toml", "../../../config.toml", "../../../../config.toml", "/etc/ros2_grade_calculator/config.toml" }; ``` #### Configuration Access **`std::optional get_database_config() const`** > Returns `std::optional` for safe null handling > Returns `std::nullopt` if: > - Configuration is not loaded > - Database section is missing > - Parsing fails due to invalid format - Calls `parse_database_config()` for actual parsing **`bool is_loaded() const`** > Returns `true` if configuration has been successfully loaded and parsed - Getter for configuration load status - Used by other components to verify configuration availability ### Configuration Parsing **`DatabaseConfig parse_database_config(const toml::table& config) const`** - parser for database configuration section - Extracts all database-related parameters with defaults #### Default Values and Fallbacks - **host**: `"localhost"` - Local database server - **port**: `5432` - Standard PostgreSQL port - **dbname**: `"grades"` - Application-specific database - **user**: `"postgres"` - Default PostgreSQL user - **password**: `"postgres"` - Default PostgreSQL password - **timeout**: `30` seconds - connection timeout - **ssl**: `false` - Disabled by default for development - **min_connections**: `1` - Minimal connection pool - **max_connections**: `10` - connection pool limit ### Logging - Uses ROS2 logger with `[CFG]` prefix for configuration operations - Includes file paths in log messages ### Usage Examples #### Automatic Configuration Loading ```cpp // ConfigManager automatically finds and loads configuration ConfigManager config_manager(node->get_logger()); if (config_manager.is_loaded()) { auto db_config = config_manager.get_database_config(); if (db_config.has_value()) { // Use database configuration DatabaseManager db_manager(db_config.value()); } } ``` ### Configuration File Format Example complete TOML configuration: ```toml # Database connection settings [database] host = "localhost" port = 5432 dbname = "grades" user = "postgres" password = "postgres" timeout = 30 ssl = false [database.pool] min_connections = 1 max_connections = 10 ```