Consolix
Loading...
Searching...
No Matches
ConfigComponent.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _CONSOLIX_CONFIG_COMPONENT_HPP_INCLUDED
3#define _CONSOLIX_CONFIG_COMPONENT_HPP_INCLUDED
4
8
9#if CONSOLIX_USE_JSON == 1
10
11#include <atomic>
12#include <fstream>
13#include <mutex>
14#include <string>
15
16#include <nlohmann/json.hpp>
17
18namespace consolix {
19
27 template <typename ConfigType>
28 class ConfigComponent : public IAppComponent {
29 public:
33 explicit ConfigComponent(
34 const std::string& default_file = "config.json",
35 const std::string& cli_flag = "--config")
36 : m_default_file(default_file), m_cli_flag(cli_flag) {
37 }
38
40 void reload() {
41 load_config();
42 }
43
44 protected:
45
48 bool initialize() override {
49# if CONSOLIX_USE_CXXOPTS == 1
50 if (has_service<CliOptions>() && !has_service<CliArguments>()) {
51 return false;
52 }
53# endif
54 load_config();
55 m_is_init = true;
56 return true;
57 }
58
61 bool is_initialized() const override {
62 return m_is_init;
63 }
64
66 void process() override {}
67
68 private:
69 std::string m_default_file;
70 std::string m_cli_flag;
71 ConfigType m_config_data;
72 std::atomic<bool> m_is_init{false};
73 std::mutex m_mutex;
74
76 void load_config() {
77 std::lock_guard<std::mutex> lock(m_mutex);
78 std::string config_path = resolve_file_path();
79# if defined(_WIN32) || defined(_WIN64)
80 std::ifstream file(utf8_to_ansi(config_path));
81# else
82 std::ifstream file(config_path);
83# endif
84
85 if (!file) {
86# if CONSOLIX_USE_LOGIT == 1
87 LOGIT_PRINT_ERROR("Failed to open config file: ", config_path);
88# endif
91 "Failed to open config file: " << config_path;
92 throw std::runtime_error("Failed to open config file: " + config_path);
93 }
94
95 try {
96 // Read file content
97 std::string json_content((std::istreambuf_iterator<char>(file)),
98 std::istreambuf_iterator<char>());
99
100 // Remove comments from the JSON string
101 json_content = strip_json_comments(json_content);
102
103 // Parse JSON
104 nlohmann::json json_data = nlohmann::json::parse(json_content);
105
106 m_config_data = json_data.get<ConfigType>();
107 store_config_service();
108 } catch (const std::exception& e) {
109# if CONSOLIX_USE_LOGIT == 1
110 LOGIT_PRINT_ERROR("Failed to parse config file: ", e.what());
111# endif
112 CONSOLIX_STREAM() <<
114 "Failed to parse config file: " << e.what();
115 throw;
116 }
117 }
118
121 std::string resolve_file_path() {
122 std::string config_path = m_default_file;
123
124# if CONSOLIX_USE_CXXOPTS == 1
125 if (has_service<CliArguments>()) {
126 auto& args = get_service<CliArguments>();
127 if (args.count(m_cli_flag)) {
128 config_path = args[m_cli_flag].template as<std::string>();
129 }
130 }
131# endif
132
133 return resolve_exec_path(config_path);
134 }
135
137 void store_config_service() {
138 if (has_service<ConfigType>()) {
139 get_service<ConfigType>() = m_config_data;
140 return;
141 }
142
143 register_service<ConfigType>([this]() {
144 return std::make_shared<ConfigType>(m_config_data);
145 });
146 }
147 };
148
149} // namespace consolix
150
151#endif // #if CONSOLIX_USE_JSON == 1
152
153#endif // _CONSOLIX_CONFIG_COMPONENT_HPP_INCLUDED
#define CONSOLIX_STREAM()
Fallback for general logging.
< Utility modules and helpers.
ColorManipulator color(TextColor color)
Creates a color manipulator for use in output streams.