diff --git a/README.md b/README.md index 5b9c8dd..816475b 100644 --- a/README.md +++ b/README.md @@ -54,40 +54,40 @@ Result: ```json { "base" : "EUR", - "date" : "2024-03-22", + "date" : "2024-03-27", "rates" : { - "AUD" : 1.6600999999999999, - "BGN" : 1.9558, - "BRL" : 5.4099000000000004, - "CAD" : 1.4688000000000001, - "CHF" : 0.97289999999999999, - "CNY" : 7.8244999999999996, - "CZK" : 25.370999999999999, - "DKK" : 7.4581, - "GBP" : 0.85794999999999999, - "HKD" : 8.4644999999999992, - "HUF" : 396.30000000000001, - "IDR" : 17111.810000000001, - "ILS" : 3.9264999999999999, - "INR" : 90.409000000000006, - "ISK" : 148.90000000000001, - "JPY" : 163.74000000000001, - "KRW" : 1453.6199999999999, - "MXN" : 18.1372, - "MYR" : 5.1273999999999997, - "NOK" : 11.617000000000001, - "NZD" : 1.802, - "PHP" : 60.927999999999997, - "PLN" : 4.3170000000000002, - "RON" : 4.9726999999999997, - "SEK" : 11.4025, - "SGD" : 1.4593, - "THB" : 39.298000000000002, - "TRY" : 34.620899999999999, - "USD" : 1.0823, - "ZAR" : 20.559699999999999 - }, + "AUD" : 1.66, + "BGN" : 1.9558, + "BRL" : 5.3969, + "CAD" : 1.4712, + "CHF" : 0.9811, + "CNY" : 7.8182, + "CZK" : 25.319, + "DKK" : 7.4582, + "GBP" : 0.85768, + "HKD" : 8.4615, + "HUF" : 395.4, + "IDR" : 17194.2, + "ILS" : 3.9582, + "INR" : 90.134, + "ISK" : 149.9, + "JPY" : 163.52, + "KRW" : 1461.31, + "MXN" : 17.9367, + "MYR" : 5.1192, + "NOK" : 11.6825, + "NZD" : 1.8043, + "PHP" : 60.849, + "PLN" : 4.3148, + "RON" : 4.9721, + "SEK" : 11.506, + "SGD" : 1.4586, + "THB" : 39.381, + "TRY" : 34.9005, + "USD" : 1.0816, + "ZAR" : 20.4716 + }, "success" : true } ``` @@ -102,14 +102,14 @@ Result: ```json { - "base" : "USD", - "date" : "2024-03-22", - "rates" : - { - "DKK" : 6.8909729280236531, - "EUR" : 0.92395823708768365, - "NOK" : 10.733622840247621 - }, - "success" : true + "base" : "USD", + "date" : "2024-03-27", + "rates" : + { + "DKK" : 6.89553, + "EUR" : 0.924556, + "NOK" : 10.8011 + }, + "success" : true } ``` diff --git a/TODO b/TODO index f1ac5aa..5fdebba 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,7 @@ + - use cmake presets -- github actions for tests - target with asan - examples of configuration (nginx, cron) -- json output - no so verbose if needed -- json output - floats limited to 4 decimal places - make cross compilation work again - consider removing ECB namespace - consider using spdlog diff --git a/src/Main_Server.cpp b/src/Main_Server.cpp index cf1fc25..1a65277 100644 --- a/src/Main_Server.cpp +++ b/src/Main_Server.cpp @@ -37,7 +37,13 @@ int main(int argc, char *argv[]) return num >= 1 && num <= 65535; // NOLINT }); + options.add_optional("precision", "Numerical precision of rates: 1..20", "6", [](const std::string &value) { + uint32_t num = Options::as_uint(value); + return num >= 1 && num <= 20; // NOLINT + }); + options.add_flag("listen_all", "Listen on all interfaces"); + options.add_flag("pretty", "Pretty print JSON output"); options.add_flag("help", "Show help"); const bool parse_result = options.parse(argc, argv); @@ -83,10 +89,16 @@ int main(int argc, char *argv[]) Main_Signals::Setup(); // handling SIGINT and SIGUSR1 const uint16_t port = options.as_uint("port"); + const uint16_t precision = options.as_uint("precision"); const bool listen_all = options.as_bool("listen_all"); + const bool pretty = options.as_bool("pretty"); cout << "Starting server on port " << port << (listen_all ? " on all interfaces" : " on localhost only") << endl; + cout << "Pretty JSON output: " << (pretty ? "yes" : "no") << endl; + cout << "Numerical precision: " << precision << endl; auto &server = ECB::Server::Instance(); + server.SetPrettyJson(pretty); + server.SetPrecision(precision); if (!server.Initialize(rates, port, listen_all)) { diff --git a/src/Main_Signals.cpp b/src/Main_Signals.cpp index 36367a6..4c75c78 100644 --- a/src/Main_Signals.cpp +++ b/src/Main_Signals.cpp @@ -2,7 +2,7 @@ #include -volatile bool Main_Signals::m_keep_running = true; // NOLINT +volatile bool Main_Signals::m_keep_running = true; // NOLINT volatile bool Main_Signals::m_load_more_data = false; // NOLINT void Main_Signals::Setup() diff --git a/src/Server.cpp b/src/Server.cpp index 13161b1..c820b77 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -19,6 +19,9 @@ namespace ECB return m_impl->initialize(ecb, listening_address); } + void Server::SetPrettyJson(bool pretty) { m_impl->set_pretty_json(pretty); } + void Server::SetPrecision(uint16_t precision) { m_impl->set_precision(precision); } + void Server::Start() { m_impl->start_polling(); } void Server::Stop() { m_impl->stop_polling(); } diff --git a/src/Server.hpp b/src/Server.hpp index 0ec362f..711f8d9 100644 --- a/src/Server.hpp +++ b/src/Server.hpp @@ -23,6 +23,10 @@ namespace ECB bool Initialize(std::shared_ptr ecb, uint16_t port, bool listen_all); + void SetPrettyJson(bool pretty); + + void SetPrecision(uint16_t precision); + void Start(); void Stop(); diff --git a/src/Server_Impl.cpp b/src/Server_Impl.cpp index bdef9ad..b775887 100644 --- a/src/Server_Impl.cpp +++ b/src/Server_Impl.cpp @@ -9,7 +9,12 @@ namespace ECB { - Server_Impl::Server_Impl() { mg_mgr_init(&m_mgr); } + Server_Impl::Server_Impl() + { + mg_mgr_init(&m_mgr); + m_json_builder["indentation"] = ""; + m_json_builder["precision"] = 6; // default is 17 + } Server_Impl::~Server_Impl() { mg_mgr_free(&m_mgr); } @@ -83,10 +88,7 @@ namespace ECB } } - std::stringstream ss; - - ss << ans; - return ss.str(); + return Json::writeString(m_json_builder, ans); } std::string Server_Impl::print_error(const std::string &msg) const @@ -95,10 +97,8 @@ namespace ECB ans["success"] = false; ans["error_text"] = msg; - std::stringstream ss; - ss << ans; - return ss.str(); + return Json::writeString(m_json_builder, ans); } void Server_Impl::handler(mg_connection *connection, int event, void *event_data) diff --git a/src/Server_Impl.hpp b/src/Server_Impl.hpp index 14f594e..02d4a67 100644 --- a/src/Server_Impl.hpp +++ b/src/Server_Impl.hpp @@ -3,6 +3,7 @@ #include "Symbol.hpp" #include "mongoose.h" +#include "json/json.h" #include #include @@ -20,6 +21,8 @@ namespace ECB ~Server_Impl(); bool initialize(std::shared_ptr rates, const std::string &listen_address); + void set_pretty_json(bool pretty) { m_json_builder["indentation"] = pretty ? " " : ""; } + void set_precision(uint16_t precision) { m_json_builder["precision"] = precision; } void start_polling(); void stop_polling() { m_running = false; } @@ -36,6 +39,7 @@ namespace ECB struct mg_connection *m_conn = nullptr; bool m_running = false; std::shared_ptr m_rates; + Json::StreamWriterBuilder m_json_builder; // must be static to be used as a callback for mongoose static void handler(mg_connection *connection, int event, void *event_data);