diff options
Diffstat (limited to 'server/src/config.cpp')
| -rw-r--r-- | server/src/config.cpp | 163 |
1 files changed, 81 insertions, 82 deletions
diff --git a/server/src/config.cpp b/server/src/config.cpp index 84c436a..e9a728b 100644 --- a/server/src/config.cpp +++ b/server/src/config.cpp | |||
| @@ -17,7 +17,7 @@ namespace routemon::config { | |||
| 17 | class location | 17 | class location |
| 18 | { | 18 | { |
| 19 | std::optional<std::pair<std::string_view, util::not_null<location const*>>> | 19 | std::optional<std::pair<std::string_view, util::not_null<location const*>>> |
| 20 | next_; | 20 | next_; |
| 21 | 21 | ||
| 22 | auto append_to(std::string& s) const -> void | 22 | auto append_to(std::string& s) const -> void |
| 23 | { | 23 | { |
| @@ -64,7 +64,7 @@ public: | |||
| 64 | catch (boost::system::system_error const&) | 64 | catch (boost::system::system_error const&) |
| 65 | { | 65 | { |
| 66 | throw std::runtime_error{std::format( | 66 | throw std::runtime_error{std::format( |
| 67 | "expected an object at {}", loc.to_string())}; | 67 | "expected an object at {}", loc.to_string())}; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | auto check_unused() const -> void | 70 | auto check_unused() const -> void |
| @@ -74,7 +74,7 @@ public: | |||
| 74 | if (!visited_.contains(std::string{kv.key()})) | 74 | if (!visited_.contains(std::string{kv.key()})) |
| 75 | { | 75 | { |
| 76 | throw std::runtime_error{std::format( | 76 | throw std::runtime_error{std::format( |
| 77 | "unexpected key {}", loc_.sub(kv.key()).to_string())}; | 77 | "unexpected key {}", loc_.sub(kv.key()).to_string())}; |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| @@ -93,21 +93,21 @@ public: | |||
| 93 | catch (boost::system::system_error const& e) | 93 | catch (boost::system::system_error const& e) |
| 94 | { | 94 | { |
| 95 | throw std::runtime_error{std::format( | 95 | throw std::runtime_error{std::format( |
| 96 | "failed to read {}: {}", loc.to_string(), e.code().message())}; | 96 | "failed to read {}: {}", loc.to_string(), e.code().message())}; |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
| 99 | else | 99 | else |
| 100 | { | 100 | { |
| 101 | throw std::runtime_error{std::format( | 101 | throw std::runtime_error{std::format( |
| 102 | "did not find expected key {}", loc.to_string())}; | 102 | "did not find expected key {}", loc.to_string())}; |
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | auto as_checked_object( | 107 | auto as_checked_object( |
| 108 | json::value const& jv, location const& loc, | 108 | json::value const& jv, location const& loc, |
| 109 | std::invocable<object_reader&> auto const& f) | 109 | std::invocable<object_reader&> auto const& f) |
| 110 | -> decltype(f(std::declval<object_reader&>())) | 110 | -> decltype(f(std::declval<object_reader&>())) |
| 111 | { | 111 | { |
| 112 | auto r = object_reader{jv, loc}; | 112 | auto r = object_reader{jv, loc}; |
| 113 | auto&& v = f(r); | 113 | auto&& v = f(r); |
| @@ -116,110 +116,109 @@ auto as_checked_object( | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | auto tag_invoke( | 118 | auto tag_invoke( |
| 119 | json::value_to_tag<rwgps> const&, json::value const& jv, | 119 | json::value_to_tag<rwgps> const&, json::value const& jv, location const& loc) |
| 120 | location const& loc) -> rwgps | 120 | -> rwgps |
| 121 | { | 121 | { |
| 122 | return as_checked_object( | 122 | return as_checked_object( |
| 123 | jv, loc, | 123 | jv, loc, |
| 124 | [](object_reader& r) -> rwgps | 124 | [](object_reader& r) -> rwgps |
| 125 | { | 125 | { |
| 126 | return { | 126 | return { |
| 127 | .api_key = r.expect_at<std::string>("api_key"), | 127 | .api_key = r.expect_at<std::string>("api_key"), |
| 128 | .auth_token = r.expect_at<std::string>("auth_token"), | 128 | .auth_token = r.expect_at<std::string>("auth_token"), |
| 129 | }; | 129 | }; |
| 130 | }); | 130 | }); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | auto tag_invoke( | 133 | auto tag_invoke( |
| 134 | json::value_to_tag<situations> const&, json::value const& jv, | 134 | json::value_to_tag<situations> const&, json::value const& jv, |
| 135 | location const& loc) -> situations | 135 | location const& loc) -> situations |
| 136 | { | 136 | { |
| 137 | return as_checked_object( | 137 | return as_checked_object( |
| 138 | jv, loc, | 138 | jv, loc, |
| 139 | [](object_reader& r) -> situations | 139 | [](object_reader& r) -> situations |
| 140 | { | 140 | { |
| 141 | return { | 141 | return { |
| 142 | .datex2_filename = r.expect_at<std::string>("datex2_filename"), | 142 | .datex2_filename = r.expect_at<std::string>("datex2_filename"), |
| 143 | }; | 143 | }; |
| 144 | }); | 144 | }); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | auto tag_invoke( | 147 | auto tag_invoke( |
| 148 | json::value_to_tag<database> const&, json::value const& jv, | 148 | json::value_to_tag<database> const&, json::value const& jv, |
| 149 | location const& loc) -> database | 149 | location const& loc) -> database |
| 150 | { | 150 | { |
| 151 | return as_checked_object( | 151 | return as_checked_object( |
| 152 | jv, loc, | 152 | jv, loc, |
| 153 | [](object_reader& r) -> database | 153 | [](object_reader& r) -> database |
| 154 | { | 154 | { |
| 155 | return { | 155 | return { |
| 156 | .sqlite3_filename = r.expect_at<std::string>("sqlite3_filename"), | 156 | .sqlite3_filename = r.expect_at<std::string>("sqlite3_filename"), |
| 157 | }; | 157 | }; |
| 158 | }); | 158 | }); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | auto tag_invoke( | 161 | auto tag_invoke( |
| 162 | json::value_to_tag<http_server> const&, json::value const& jv, | 162 | json::value_to_tag<http_server> const&, json::value const& jv, |
| 163 | location const& loc) -> http_server | 163 | location const& loc) -> http_server |
| 164 | { | 164 | { |
| 165 | return as_checked_object( | 165 | return as_checked_object( |
| 166 | jv, loc, | 166 | jv, loc, |
| 167 | [](object_reader& r) -> http_server | 167 | [](object_reader& r) -> http_server |
| 168 | { | 168 | { |
| 169 | return { | 169 | return { |
| 170 | .lax_cors = r.expect_at<bool>("lax_cors"), | 170 | .lax_cors = r.expect_at<bool>("lax_cors"), |
| 171 | }; | 171 | }; |
| 172 | }); | 172 | }); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | auto tag_invoke( | 175 | auto tag_invoke( |
| 176 | json::value_to_tag<logger> const&, json::value const& jv, | 176 | json::value_to_tag<logger> const&, json::value const& jv, location const& loc) |
| 177 | location const& loc) -> logger | 177 | -> logger |
| 178 | { | 178 | { |
| 179 | return as_checked_object( | 179 | return as_checked_object( |
| 180 | jv, loc, | 180 | jv, loc, |
| 181 | [obj_loc = loc](object_reader& r) -> logger | 181 | [obj_loc = loc](object_reader& r) -> logger |
| 182 | { | 182 | { |
| 183 | auto const level_str = r.expect_at<std::string>("level"); | 183 | auto const level_str = r.expect_at<std::string>("level"); |
| 184 | auto level = log::level{}; | 184 | auto level = log::level{}; |
| 185 | if (level_str == "debug") | 185 | if (level_str == "debug") |
| 186 | level = log::level::debug; | 186 | level = log::level::debug; |
| 187 | else if (level_str == "info") | 187 | else if (level_str == "info") |
| 188 | level = log::level::info; | 188 | level = log::level::info; |
| 189 | else if (level_str == "warn") | 189 | else if (level_str == "warn") |
| 190 | level = log::level::warn; | 190 | level = log::level::warn; |
| 191 | else if (level_str == "error") | 191 | else if (level_str == "error") |
| 192 | level = log::level::error; | 192 | level = log::level::error; |
| 193 | else | 193 | else |
| 194 | throw std::runtime_error{std::format( | 194 | throw std::runtime_error{std::format( |
| 195 | "unable to parse log level {:?} at {}: expected one " | 195 | "unable to parse log level {:?} at {}: expected one " |
| 196 | "of {{debug, info, warn, error}}", | 196 | "of {{debug, info, warn, error}}", |
| 197 | level_str, obj_loc.sub("level").to_string())}; | 197 | level_str, obj_loc.sub("level").to_string())}; |
| 198 | return logger{level}; | 198 | return logger{level}; |
| 199 | }); | 199 | }); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | auto json_value_to_app(json::value const& jv) -> app | 202 | auto json_value_to_app(json::value const& jv) -> app |
| 203 | { | 203 | { |
| 204 | return as_checked_object( | 204 | return as_checked_object( |
| 205 | jv, location{}, | 205 | jv, location{}, |
| 206 | [](object_reader& r) -> app | 206 | [](object_reader& r) -> app |
| 207 | { | 207 | { |
| 208 | return { | 208 | return { |
| 209 | .rwgps = r.expect_at<rwgps>("rwgps"), | 209 | .rwgps = r.expect_at<rwgps>("rwgps"), |
| 210 | .situations = r.expect_at<situations>("situations"), | 210 | .situations = r.expect_at<situations>("situations"), |
| 211 | .database = r.expect_at<database>("database"), | 211 | .database = r.expect_at<database>("database"), |
| 212 | .http_server = r.expect_at<http_server>("http_server"), | 212 | .http_server = r.expect_at<http_server>("http_server"), |
| 213 | .logger = r.expect_at<logger>("logger"), | 213 | .logger = r.expect_at<logger>("logger"), |
| 214 | }; | 214 | }; |
| 215 | }); | 215 | }); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | auto load_file(std::string const& filename) -> app | 218 | auto load_file(std::string const& filename) -> app |
| 219 | { | 219 | { |
| 220 | auto f = std::ifstream{ | 220 | auto f = |
| 221 | filename | 221 | std::ifstream{filename}; // TODO: ensure that we are opening in binary mode? |
| 222 | }; // TODO: ensure that we are opening in binary mode? | ||
| 223 | if (!f.is_open()) | 222 | if (!f.is_open()) |
| 224 | throw std::runtime_error{std::format("failed to open {}", filename)}; | 223 | throw std::runtime_error{std::format("failed to open {}", filename)}; |
| 225 | auto jv = json::value{}; | 224 | auto jv = json::value{}; |
| @@ -230,7 +229,7 @@ auto load_file(std::string const& filename) -> app | |||
| 230 | catch (boost::system::system_error const& e) | 229 | catch (boost::system::system_error const& e) |
| 231 | { | 230 | { |
| 232 | throw std::runtime_error{std::format( | 231 | throw std::runtime_error{std::format( |
| 233 | "failed to parse: {}", e.code().message())}; | 232 | "failed to parse: {}", e.code().message())}; |
| 234 | } | 233 | } |
| 235 | return json_value_to_app(jv); | 234 | return json_value_to_app(jv); |
| 236 | } | 235 | } |