From 35878b76049b9c3e752480e9f298b7e2da6fdf1f Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Fri, 28 Aug 2026 23:29:00 +0200 Subject: Make RWGPS config optional --- server/src/config.cpp | 40 +++++++++++++++++++++++++++++----------- server/src/config.cppm | 6 +++--- server/src/main.cpp | 7 ------- server/src/srv.cppm | 3 +++ 4 files changed, 35 insertions(+), 21 deletions(-) (limited to 'server/src') diff --git a/server/src/config.cpp b/server/src/config.cpp index eab97b5..5c1a161 100644 --- a/server/src/config.cpp +++ b/server/src/config.cpp @@ -23,9 +23,9 @@ class location { if (next_) { + next_->second->append_to(s); s += next_->first; s += "."; - next_->second->append_to(s); } } @@ -41,8 +41,9 @@ public: { if (!next_) return ""; - auto s = std::string{next_->first}; + auto s = std::string{}; next_->second->append_to(s); + s += next_->first; return s; } @@ -80,11 +81,11 @@ public: } template - auto expect_at(std::string_view key) -> T + auto allow_at(std::string_view key) -> std::optional { visited_.emplace(key); auto const loc = loc_.sub(key); - if (auto const jv = obj_.try_at(key)) + if (auto const jv = obj_.try_at(key); jv && !jv->is_null()) { try { @@ -97,9 +98,22 @@ public: } } else + { + return std::nullopt; + } + } + + template + auto expect_at(std::string_view key) -> T + { + if (auto&& mv = allow_at(key); mv) + { + return std::forward(*mv); + } + else { throw std::runtime_error{std::format( - "did not find expected key {}", loc.to_string())}; + "did not find expected key {}", loc_.sub(key).to_string())}; } } }; @@ -124,8 +138,9 @@ auto tag_invoke( [](object_reader& r) -> rwgps { return { - .api_key = r.expect_at("api_key"), - .auth_token = r.expect_at("auth_token"), + .api_key_filename = r.expect_at("api_key_filename"), + .auth_token_filename = + r.expect_at("auth_token_filename"), }; }); } @@ -206,7 +221,7 @@ auto json_value_to_app(json::value const& jv) -> app [](object_reader& r) -> app { return { - .rwgps = r.expect_at("rwgps"), + .rwgps = r.allow_at("rwgps"), .situations = r.expect_at("situations"), .database = r.expect_at("database"), .http_server = r.expect_at("http_server"), @@ -217,9 +232,12 @@ auto json_value_to_app(json::value const& jv) -> app auto load_file(std::string const& filename) -> app { - auto f = std::ifstream{ - filename - }; // TODO: ensure that we are opening in binary mode? + // TODO: migrate away from json::value_to w/ tag_invoke. + // Boost.JSON does not properly propagate custom exceptions accross + // json::value_to calls when certain containers are involved + // (std::{optional,variant,vector}). + + auto f = std::ifstream{filename, std::ios::binary}; if (!f.is_open()) throw std::runtime_error{std::format("failed to open {}", filename)}; auto jv = json::value{}; diff --git a/server/src/config.cppm b/server/src/config.cppm index e5b48f4..358a961 100644 --- a/server/src/config.cppm +++ b/server/src/config.cppm @@ -7,8 +7,8 @@ namespace routemon::config { export struct rwgps { - std::string api_key; - std::string auth_token; + std::string api_key_filename; + std::string auth_token_filename; }; export struct situations @@ -33,7 +33,7 @@ export struct logger export struct app { - rwgps rwgps; + std::optional rwgps; situations situations; database database; http_server http_server; diff --git a/server/src/main.cpp b/server/src/main.cpp index 3f8cb11..d5fcd42 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -52,13 +52,6 @@ auto real_main(std::span args) -> exit_status return exit_status::failure; } sink->set_level(config.logger.level); - // auto rwgps_client = routemon::rwgps::client{ioc, l, config.rwgps.api_key, - // config.rwgps.auth_token}; for (auto route : - // rwgps_client.get_all_routes()) - // { - // l.info("Route {} (user {}): {} @ {}", route.id, route.user_id, - // route.name, route.url); - // } auto dbc = std::shared_ptr{}; try diff --git a/server/src/srv.cppm b/server/src/srv.cppm index aef28f4..904bf1a 100644 --- a/server/src/srv.cppm +++ b/server/src/srv.cppm @@ -36,17 +36,20 @@ class gpx_parse_error_category_impl : public std::error_category { public: char const* name() const noexcept override { return "gpx_parse"; } + auto message(int condition) const noexcept -> std::string override { std::ignore = condition; return "failed to parse GPX file"; } }; + auto gpx_parse_error_category() noexcept -> gpx_parse_error_category_impl const& { static auto const inst = gpx_parse_error_category_impl{}; return inst; } + auto gpx_parse_error() noexcept -> std::error_code { return std::error_code{1, gpx_parse_error_category()}; -- cgit v1.3