| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #pragma once
- #include <string>
- #include <optional>
- #include <filesystem>
- #include <nlohmann/json.hpp>
- #include "common/error.hpp"
- namespace smartbotic::config {
- class ConfigLoader {
- public:
- // Load configuration from file
- static common::Result<nlohmann::json> loadFromFile(const std::filesystem::path& path);
- // Load configuration from string
- static common::Result<nlohmann::json> loadFromString(const std::string& content);
- // Expand environment variables in JSON values (${VAR:default})
- static nlohmann::json expandEnvVars(const nlohmann::json& config);
- // Get nested value with dot notation (e.g., "database.host")
- static std::optional<nlohmann::json> get(const nlohmann::json& config,
- const std::string& path);
- // Get value with default
- template<typename T>
- static T getOr(const nlohmann::json& config, const std::string& path, T defaultValue) {
- auto value = get(config, path);
- if (value.has_value()) {
- try {
- return value->get<T>();
- } catch (...) {
- return defaultValue;
- }
- }
- return defaultValue;
- }
- // Merge two configurations (second overrides first)
- static nlohmann::json merge(const nlohmann::json& base, const nlohmann::json& override);
- // Validate config against schema
- static common::Result<void> validate(const nlohmann::json& config,
- const nlohmann::json& schema);
- };
- // Configuration holder with typed accessors
- class Config {
- public:
- Config() = default;
- explicit Config(nlohmann::json data);
- // Load from file
- static common::Result<Config> fromFile(const std::filesystem::path& path);
- // Raw access
- const nlohmann::json& data() const { return data_; }
- nlohmann::json& data() { return data_; }
- // Get value with path
- template<typename T>
- std::optional<T> get(const std::string& path) const {
- auto value = ConfigLoader::get(data_, path);
- if (value.has_value()) {
- try {
- return value->get<T>();
- } catch (...) {
- return std::nullopt;
- }
- }
- return std::nullopt;
- }
- // Get value with default
- template<typename T>
- T getOr(const std::string& path, T defaultValue) const {
- return ConfigLoader::getOr(data_, path, std::move(defaultValue));
- }
- // Get required value (throws if not found)
- template<typename T>
- T getRequired(const std::string& path) const {
- auto value = get<T>(path);
- if (!value.has_value()) {
- throw common::SmartBoticException(
- common::Error(common::ErrorCode::InvalidArgument,
- "Required config value not found: " + path));
- }
- return *value;
- }
- // Check if path exists
- bool has(const std::string& path) const;
- // Reload from file
- common::Result<void> reload(const std::filesystem::path& path);
- private:
- nlohmann::json data_;
- };
- } // namespace smartbotic::config
|