From 70643a9e4821bd11c3f363f1708fe420965467d1 Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Fri, 28 Aug 2026 22:17:10 +0200 Subject: Format again --- server/src/api.cpp | 155 +++++++++--------- server/src/api.cppm | 24 ++- server/src/config.cpp | 163 +++++++++--------- server/src/database.cppm | 8 +- server/src/datex2.cppm | 142 ++++++++-------- server/src/geo.cppm | 34 ++-- server/src/gpx.cpp | 66 ++++---- server/src/http_client.cppm | 6 +- server/src/http_server.cppm | 390 ++++++++++++++++++++++---------------------- server/src/locale.cppm | 39 +++-- server/src/log.cppm | 14 +- server/src/main.cpp | 36 ++-- server/src/problem.cppm | 10 +- server/src/req_ctx.cppm | 8 +- server/src/rwgps.cppm | 50 +++--- server/src/sqlite3.cppm | 86 +++++----- server/src/srv.cppm | 94 ++++++----- server/src/time.cppm | 4 +- server/src/trace.cppm | 14 +- server/src/util.cppm | 25 ++- server/src/xml.cpp | 6 +- server/src/xml.cppm | 144 ++++++++-------- 22 files changed, 748 insertions(+), 770 deletions(-) diff --git a/server/src/api.cpp b/server/src/api.cpp index a6eef23..73dee32 100644 --- a/server/src/api.cpp +++ b/server/src/api.cpp @@ -39,7 +39,7 @@ auto json_value_from_linestring(geo::linestring const& ls) -> json::value } auto json_value_from_linestrings(std::vector const& lss) - -> json::value + -> json::value { json::array a; for (auto const& ls : lss) @@ -48,59 +48,56 @@ auto json_value_from_linestrings(std::vector const& lss) } auto tag_invoke( - json::value_from_tag, json::value& jv, relevant_road_closure const& clo) - -> void + json::value_from_tag, json::value& jv, relevant_road_closure const& clo) + -> void { jv = json::object{ - {"relevant_lss", json_value_from_linestrings(clo.relevant_lss)}, + {"relevant_lss", json_value_from_linestrings(clo.relevant_lss)}, }; } auto tag_invoke( - json::value_from_tag, json::value& jv, relevant_situation const& sit) - -> void + json::value_from_tag, json::value& jv, relevant_situation const& sit) -> void { jv = json::object{ - {"id", json::value_from(sit.id)}, - {"location", - sit.location ? json_value_from_point(*sit.location) : nullptr}, - {"comments", json::value_from(sit.comments)}, - {"relevant_road_closures", json::value_from(sit.relevant_road_closures)}, + {"id", json::value_from(sit.id)}, + {"location", sit.location ? json_value_from_point(*sit.location) : nullptr}, + {"comments", json::value_from(sit.comments)}, + {"relevant_road_closures", json::value_from(sit.relevant_road_closures)}, }; } auto tag_invoke(json::value_from_tag, json::value& jv, track_segment const& seg) - -> void + -> void { jv = json::object{ - {"points", json_value_from_linestring(seg.points)}, + {"points", json_value_from_linestring(seg.points)}, }; } auto tag_invoke(json::value_from_tag, json::value& jv, track const& track) - -> void + -> void { jv = json::object{ - {"segments", json::value_from(track.segments)}, + {"segments", json::value_from(track.segments)}, }; } auto tag_invoke( - json::value_from_tag, json::value& jv, process_gpx_result const& res) - -> void + json::value_from_tag, json::value& jv, process_gpx_result const& res) -> void { jv = json::object{ - {"tracks", json::value_from(res.tracks)}, - {"relevant_situations", json::value_from(res.relevant_situations)}, + {"tracks", json::value_from(res.tracks)}, + {"relevant_situations", json::value_from(res.relevant_situations)}, }; } auto tag_invoke(json::value_from_tag, json::value& jv, sysinfo const& info) - -> void + -> void { jv = json::object{ - {"using_publication_of", - std::format("{:%FT%TZ}", info.using_publication_of)}, + {"using_publication_of", + std::format("{:%FT%TZ}", info.using_publication_of)}, }; } @@ -127,18 +124,18 @@ handler::handler(log::logger const& l, datex2::situation_publication pub) } auto const after_build = chrono::steady_clock::now(); auto const dur_build = - chrono::duration_cast(after_build - before_build); + chrono::duration_cast(after_build - before_build); l_.info("Indices built in {}", dur_build); l_.info("LSE index size: {}", lse_index_.size()); l_.info("Point index size: {}", p_index_.size()); } auto handler::process_gpx(gpx::file&& gpx_file) - -> std::optional + -> std::optional { auto const now = chrono::utc_clock::now(); auto const relevant = std::initializer_list{ - time::period{now - chrono::days(7), now + chrono::days(7)} + time::period{now - chrono::days(7), now + chrono::days(7)} }; auto const check_periods = time::period_seq{relevant.begin(), relevant.end()}; @@ -146,14 +143,14 @@ auto handler::process_gpx(gpx::file&& gpx_file) for (auto const& track : gpx_file.tracks) for (auto const& seg : track.segments) geo::split_linestring_with_overlap_segments( - seg.waypoints, - 5000 /* meters max total dist until a new split is forced */, - splits_with_overlap_segments); + seg.waypoints, + 5000 /* meters max total dist until a new split is forced */, + splits_with_overlap_segments); auto const before_query = chrono::steady_clock::now(); l_.debug("Querying for relevant situations"); auto relevant_road_closures = - std::unordered_set>{}; + std::unordered_set>{}; auto ls_checked = 0uz; auto p_checked = 0uz; auto i = 0; @@ -200,70 +197,66 @@ auto handler::process_gpx(gpx::file&& gpx_file) auto const after_query = chrono::steady_clock::now(); l_.debug( - "Done (checked {} line string(s) and {} point(s)) in {}", ls_checked, - p_checked, - chrono::duration_cast(after_query - before_query)); + "Done (checked {} line string(s) and {} point(s)) in {}", ls_checked, + p_checked, + chrono::duration_cast(after_query - before_query)); auto relevant_situations = - std::unordered_set>{}; + std::unordered_set>{}; for (auto const& rc : relevant_road_closures) relevant_situations.emplace(rc->parent); l_.debug( - "Identified {} relevant road closure(s), part of {} unique " - "situation(s)", - relevant_road_closures.size(), relevant_situations.size()); + "Identified {} relevant road closure(s), part of {} unique " + "situation(s)", + relevant_road_closures.size(), relevant_situations.size()); for (auto const& sit : relevant_situations) l_.debug("Relevant situation: {}", sit->id); return process_gpx_result{ - .tracks = gpx_file.tracks - | views::transform( - [](auto const& trk) -> track - { - return { - .segments = - trk.segments - | views::transform( + .tracks = gpx_file.tracks + | views::transform( + [](auto const& trk) -> track + { + return { + .segments = trk.segments + | views::transform( [](auto const& seg) -> track_segment { return {.points = seg.waypoints}; }) - | std::ranges::to>(), - }; - }) - | std::ranges::to>(), - .relevant_situations = - relevant_situations - | views::transform( - [&](std::shared_ptr sit) -> relevant_situation - { - return { - .id = sit->id, - .location = sit->location, - .comments = sit->comments, - .relevant_road_closures = - relevant_road_closures - | views::filter( - [&](std::shared_ptr const& rc) - -> bool - { return std::shared_ptr{rc->parent} == sit; }) - | views::transform( - [](std::shared_ptr const& rc) - -> relevant_road_closure - { - return { - .relevant_lss = - rc->relevant_line_strings - | views::transform( - [](auto const& lsp) -> geo::linestring - { return *lsp; }) - | std::ranges::to< - std::vector>(), - }; - }) - | std::ranges::to>(), - }; - }) - | std::ranges::to>(), + | std::ranges::to>(), + }; + }) + | std::ranges::to>(), + .relevant_situations = + relevant_situations + | views::transform( + [&](std::shared_ptr sit) -> relevant_situation + { + return { + .id = sit->id, + .location = sit->location, + .comments = sit->comments, + .relevant_road_closures = + relevant_road_closures + | views::filter( + [&](std::shared_ptr const& rc) -> bool + { return std::shared_ptr{rc->parent} == sit; }) + | views::transform( + [](std::shared_ptr const& rc) + -> relevant_road_closure + { + return { + .relevant_lss = + rc->relevant_line_strings + | views::transform( + [](auto const& lsp) -> geo::linestring { return *lsp; }) + | std::ranges::to>(), + }; + }) + | std::ranges::to>(), + }; + }) + | std::ranges::to>(), }; } diff --git a/server/src/api.cppm b/server/src/api.cppm index 66e8f45..c724a45 100644 --- a/server/src/api.cppm +++ b/server/src/api.cppm @@ -58,30 +58,28 @@ struct sysinfo }; auto tag_invoke( - json::value_from_tag, json::value& jv, relevant_road_closure const& clo) - -> void; + json::value_from_tag, json::value& jv, relevant_road_closure const& clo) + -> void; auto tag_invoke( - json::value_from_tag, json::value& jv, relevant_situation const& sit) - -> void; + json::value_from_tag, json::value& jv, relevant_situation const& sit) -> void; auto tag_invoke(json::value_from_tag, json::value& jv, track_segment const& seg) - -> void; + -> void; auto tag_invoke(json::value_from_tag, json::value& jv, track const& track) - -> void; + -> void; auto tag_invoke( - json::value_from_tag, json::value& jv, process_gpx_result const& res) - -> void; + json::value_from_tag, json::value& jv, process_gpx_result const& res) -> void; auto tag_invoke(json::value_from_tag, json::value& jv, sysinfo const& info) - -> void; + -> void; class handler { using lse_index_value = std::tuple< - geo::box, std::shared_ptr, - std::shared_ptr>; + geo::box, std::shared_ptr, + std::shared_ptr>; using p_index_value = - std::pair>; + std::pair>; using lse_index = - bgeo::index::rtree>; + bgeo::index::rtree>; using p_index = bgeo::index::rtree>; log::logger l_; 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 { class location { std::optional>> - next_; + next_; auto append_to(std::string& s) const -> void { @@ -64,7 +64,7 @@ public: catch (boost::system::system_error const&) { throw std::runtime_error{std::format( - "expected an object at {}", loc.to_string())}; + "expected an object at {}", loc.to_string())}; } auto check_unused() const -> void @@ -74,7 +74,7 @@ public: if (!visited_.contains(std::string{kv.key()})) { throw std::runtime_error{std::format( - "unexpected key {}", loc_.sub(kv.key()).to_string())}; + "unexpected key {}", loc_.sub(kv.key()).to_string())}; } } } @@ -93,21 +93,21 @@ public: catch (boost::system::system_error const& e) { throw std::runtime_error{std::format( - "failed to read {}: {}", loc.to_string(), e.code().message())}; + "failed to read {}: {}", loc.to_string(), e.code().message())}; } } else { throw std::runtime_error{std::format( - "did not find expected key {}", loc.to_string())}; + "did not find expected key {}", loc.to_string())}; } } }; auto as_checked_object( - json::value const& jv, location const& loc, - std::invocable auto const& f) - -> decltype(f(std::declval())) + json::value const& jv, location const& loc, + std::invocable auto const& f) + -> decltype(f(std::declval())) { auto r = object_reader{jv, loc}; auto&& v = f(r); @@ -116,110 +116,109 @@ auto as_checked_object( } auto tag_invoke( - json::value_to_tag const&, json::value const& jv, - location const& loc) -> rwgps + json::value_to_tag const&, json::value const& jv, location const& loc) + -> rwgps { return as_checked_object( - jv, loc, - [](object_reader& r) -> rwgps - { - return { - .api_key = r.expect_at("api_key"), - .auth_token = r.expect_at("auth_token"), - }; - }); + jv, loc, + [](object_reader& r) -> rwgps + { + return { + .api_key = r.expect_at("api_key"), + .auth_token = r.expect_at("auth_token"), + }; + }); } auto tag_invoke( - json::value_to_tag const&, json::value const& jv, - location const& loc) -> situations + json::value_to_tag const&, json::value const& jv, + location const& loc) -> situations { return as_checked_object( - jv, loc, - [](object_reader& r) -> situations - { - return { - .datex2_filename = r.expect_at("datex2_filename"), - }; - }); + jv, loc, + [](object_reader& r) -> situations + { + return { + .datex2_filename = r.expect_at("datex2_filename"), + }; + }); } auto tag_invoke( - json::value_to_tag const&, json::value const& jv, - location const& loc) -> database + json::value_to_tag const&, json::value const& jv, + location const& loc) -> database { return as_checked_object( - jv, loc, - [](object_reader& r) -> database - { - return { - .sqlite3_filename = r.expect_at("sqlite3_filename"), - }; - }); + jv, loc, + [](object_reader& r) -> database + { + return { + .sqlite3_filename = r.expect_at("sqlite3_filename"), + }; + }); } auto tag_invoke( - json::value_to_tag const&, json::value const& jv, - location const& loc) -> http_server + json::value_to_tag const&, json::value const& jv, + location const& loc) -> http_server { return as_checked_object( - jv, loc, - [](object_reader& r) -> http_server - { - return { - .lax_cors = r.expect_at("lax_cors"), - }; - }); + jv, loc, + [](object_reader& r) -> http_server + { + return { + .lax_cors = r.expect_at("lax_cors"), + }; + }); } auto tag_invoke( - json::value_to_tag const&, json::value const& jv, - location const& loc) -> logger + json::value_to_tag const&, json::value const& jv, location const& loc) + -> logger { return as_checked_object( - jv, loc, - [obj_loc = loc](object_reader& r) -> logger - { - auto const level_str = r.expect_at("level"); - auto level = log::level{}; - if (level_str == "debug") - level = log::level::debug; - else if (level_str == "info") - level = log::level::info; - else if (level_str == "warn") - level = log::level::warn; - else if (level_str == "error") - level = log::level::error; - else - throw std::runtime_error{std::format( - "unable to parse log level {:?} at {}: expected one " - "of {{debug, info, warn, error}}", - level_str, obj_loc.sub("level").to_string())}; - return logger{level}; - }); + jv, loc, + [obj_loc = loc](object_reader& r) -> logger + { + auto const level_str = r.expect_at("level"); + auto level = log::level{}; + if (level_str == "debug") + level = log::level::debug; + else if (level_str == "info") + level = log::level::info; + else if (level_str == "warn") + level = log::level::warn; + else if (level_str == "error") + level = log::level::error; + else + throw std::runtime_error{std::format( + "unable to parse log level {:?} at {}: expected one " + "of {{debug, info, warn, error}}", + level_str, obj_loc.sub("level").to_string())}; + return logger{level}; + }); } auto json_value_to_app(json::value const& jv) -> app { return as_checked_object( - jv, location{}, - [](object_reader& r) -> app - { - return { - .rwgps = r.expect_at("rwgps"), - .situations = r.expect_at("situations"), - .database = r.expect_at("database"), - .http_server = r.expect_at("http_server"), - .logger = r.expect_at("logger"), - }; - }); + jv, location{}, + [](object_reader& r) -> app + { + return { + .rwgps = r.expect_at("rwgps"), + .situations = r.expect_at("situations"), + .database = r.expect_at("database"), + .http_server = r.expect_at("http_server"), + .logger = r.expect_at("logger"), + }; + }); } auto load_file(std::string const& filename) -> app { - auto f = std::ifstream{ - filename - }; // TODO: ensure that we are opening in binary mode? + auto f = + std::ifstream{filename}; // TODO: ensure that we are opening in binary mode? if (!f.is_open()) throw std::runtime_error{std::format("failed to open {}", filename)}; auto jv = json::value{}; @@ -230,7 +229,7 @@ auto load_file(std::string const& filename) -> app catch (boost::system::system_error const& e) { throw std::runtime_error{std::format( - "failed to parse: {}", e.code().message())}; + "failed to parse: {}", e.code().message())}; } return json_value_to_app(jv); } diff --git a/server/src/database.cppm b/server/src/database.cppm index 86ed0d7..c31d610 100644 --- a/server/src/database.cppm +++ b/server/src/database.cppm @@ -31,15 +31,15 @@ export auto open(std::string const& filename) -> std::shared_ptr if (version != expected_database_version) { throw std::runtime_error{std::format( - "database migration version ({}) does not match expected " - "version ({}), consider running migrations", - *version, expected_database_version)}; + "database migration version ({}) does not match expected " + "version ({}), consider running migrations", + *version, expected_database_version)}; } } catch (std::exception const& e) { throw std::runtime_error{std::format( - "failed to query database version: {}", e.what())}; + "failed to query database version: {}", e.what())}; } return std::shared_ptr{new connection{std::move(dbc)}}; } diff --git a/server/src/datex2.cppm b/server/src/datex2.cppm index b4c795f..7c20347 100644 --- a/server/src/datex2.cppm +++ b/server/src/datex2.cppm @@ -31,7 +31,7 @@ export struct situation { std::string id; std::optional location = - std::nullopt; // as shown on the map, not used for querying + std::nullopt; // as shown on the map, not used for querying std::vector comments = {}; std::vector> road_closures = {}; }; @@ -54,13 +54,13 @@ export class loader { // ETRS 89 (EPSG:4258) -> WGS 84 (EPSG:4326) bgeo::srs::transformation< - bgeo::srs::static_epsg<4258>, bgeo::srs::static_epsg<4326>> - etrs89_to_wgs84_{}; + bgeo::srs::static_epsg<4258>, bgeo::srs::static_epsg<4326>> + etrs89_to_wgs84_{}; std::multiset warnings_; auto add_location_from_xml(road_closure& rc, pugi::xml_node const& loc_xml) - -> void + -> void { auto loc_xml_type = std::string_view{loc_xml.attribute("xsi:type").value()}; if (loc_xml_type == "loc:ItineraryByIndexedLocations") @@ -79,15 +79,15 @@ export class loader return; auto const srs_name = - std::string_view{loc_gml_xml.attribute("srsName").value()}; + std::string_view{loc_gml_xml.attribute("srsName").value()}; if (srs_name != "WGS 84"sv) { warnings_.insert( - std::format("don't now how to handle the CRS {}", srs_name)); + std::format("don't now how to handle the CRS {}", srs_name)); return; } auto const pos_list_str = - std::string_view{loc_gml_xml.child_value("loc:posList")}; + std::string_view{loc_gml_xml.child_value("loc:posList")}; // lat1 long1 lat2 long2 ... lat(n-1) long(n-1) latn longn auto ls = std::make_shared(); @@ -97,13 +97,13 @@ export class loader for (auto const lat_or_long_str : std::views::split(pos_list_str, " "sv)) { auto mlat_or_long = - util::parse_double(std::string_view{lat_or_long_str}); + util::parse_double(std::string_view{lat_or_long_str}); if (!mlat_or_long) { warnings_.insert( - std::format( - "failed to parse coordinate {:?}", - std::string_view{lat_or_long_str})); + std::format( + "failed to parse coordinate {:?}", + std::string_view{lat_or_long_str})); return; } @@ -131,7 +131,7 @@ export class loader else if (loc_xml_type == "loc:PointLocation") { auto const& coords_xml = - loc_xml.child("loc:pointByCoordinates").child("loc:pointCoordinates"); + loc_xml.child("loc:pointByCoordinates").child("loc:pointCoordinates"); if (!coords_xml) return; @@ -157,28 +157,28 @@ export class loader else { warnings_.insert( - std::format( - "don't know how to hande location of type {}, ignoring", - loc_xml.attribute("xsi:type").value())); + std::format( + "don't know how to hande location of type {}, ignoring", + loc_xml.attribute("xsi:type").value())); return; } } auto handle_road_or_carriageway_or_lane_management( - pugi::xml_node const& record_xml, std::weak_ptr parent) - -> std::optional> + pugi::xml_node const& record_xml, std::weak_ptr parent) + -> std::optional> { auto const type = - std::string_view{record_xml - .child("sit:roadOrCarriagewayOrLaneManagementType") - .child_value()}; + std::string_view{record_xml + .child("sit:roadOrCarriagewayOrLaneManagementType") + .child_value()}; if (type != "carriagewayClosures" && type != "roadClosed") // TODO: checken of er nog andere types fietsers de doorgang zouden // kunnen blokkeren? return std::nullopt; auto const& restricted_vehicle_types_xml = - record_xml.child("sit:forVehiclesWithCharacteristicsOf"); + record_xml.child("sit:forVehiclesWithCharacteristicsOf"); bool likely_restriction_for_bikes = restricted_vehicle_types_xml.empty(); for (auto const vehicle_type_xml : restricted_vehicle_types_xml.children("com:vehicleType")) @@ -199,20 +199,20 @@ export class loader auto const& validity_xml = record_xml.child("sit:validity"); if (validity_xml && validity_xml.child_value("com:validityStatus") - == "definedByValidityTimeSpec"sv) + == "definedByValidityTimeSpec"sv) { auto const& validity_spec_xml = - validity_xml.child("com:validityTimeSpecification"); + validity_xml.child("com:validityTimeSpecification"); auto valid_periods = std::vector{}; auto exception_periods = std::vector{}; // TODO: com:overallEndTime may be missing (according to the DATEX // II v3 data model) - auto const overall_start_time = parse_timestamp( - validity_spec_xml.child_value("com:overallStartTime")); + auto const overall_start_time = + parse_timestamp(validity_spec_xml.child_value("com:overallStartTime")); auto const overall_end_time = - parse_timestamp(validity_spec_xml.child_value("com:overallEndTime")); + parse_timestamp(validity_spec_xml.child_value("com:overallEndTime")); if (overall_start_time && overall_end_time && *overall_start_time < *overall_end_time) { @@ -221,10 +221,10 @@ export class loader for (auto const valid_period_xml : validity_xml.children("com:validPeriod")) { - auto const start_of_period = parse_timestamp( - valid_period_xml.child_value("com:startOfPeriod")); + auto const start_of_period = + parse_timestamp(valid_period_xml.child_value("com:startOfPeriod")); auto const end_of_period = - parse_timestamp(valid_period_xml.child_value("com:endOfPeriod")); + parse_timestamp(valid_period_xml.child_value("com:endOfPeriod")); if (start_of_period && end_of_period && *start_of_period < *end_of_period) { @@ -235,9 +235,9 @@ export class loader validity_xml.children("com:exceptionPeriod")) { auto const start_of_period = parse_timestamp( - exception_period_xml.child_value("com:startOfPeriod")); + exception_period_xml.child_value("com:startOfPeriod")); auto const end_of_period = parse_timestamp( - exception_period_xml.child_value("com:endOfPeriod")); + exception_period_xml.child_value("com:endOfPeriod")); if (start_of_period && end_of_period && *start_of_period < *end_of_period) { @@ -246,19 +246,19 @@ export class loader } validity = - time::period_seq{valid_periods.begin(), valid_periods.end()}.except( - time::period_seq{ - exception_periods.begin(), exception_periods.end() - }); + time::period_seq{valid_periods.begin(), valid_periods.end()}.except( + time::period_seq{ + exception_periods.begin(), exception_periods.end() + }); } else { warnings_.insert( - std::format( - "invalid overall start / end time (start time: {}, end " - "time: {})", - validity_spec_xml.child_value("com:overallStartTime"), - validity_spec_xml.child_value("com:overallEndTime"))); + std::format( + "invalid overall start / end time (start time: {}, end " + "time: {})", + validity_spec_xml.child_value("com:overallStartTime"), + validity_spec_xml.child_value("com:overallEndTime"))); return std::nullopt; } } @@ -272,7 +272,7 @@ export class loader public: [[nodiscard]] auto load_situation_publication(std::string const& filename) - -> situation_publication + -> situation_publication { auto doc = pugi::xml_document{}; if (auto result = doc.load_file(filename.c_str()); !result) @@ -281,10 +281,10 @@ public: } auto payload_xml = doc.child("mc:messageContainer").child("mc:payload"); auto mpublication_time = - parse_timestamp(payload_xml.child_value("com:publicationTime")); + parse_timestamp(payload_xml.child_value("com:publicationTime")); if (!mpublication_time) throw std::runtime_error{ - "provided publication does not name publication time" + "provided publication does not name publication time" }; auto situations = std::vector>{}; @@ -302,26 +302,26 @@ public: for (auto const record_xml : sit_xml.children("sit:situationRecord")) { auto const record_type = - std::string_view{record_xml.attribute("xsi:type").value()}; + std::string_view{record_xml.attribute("xsi:type").value()}; auto const primary_record_types = std::unordered_set{ - "sit:Roadworks", - /* { */ "sit:MaintenanceWorks", - /* | */ "sit:ConstructionWorks", - /* } */ - "sit:Obstruction", - /* { */ "sit:EnvironmentalObstruction", - /* | */ "sit:GeneralObstruction", - /* | */ "sit:InfrastructureDamageObstruction", - /* } */ - "sit:Activity", - /* { */ "sit:PublicEvent", - /* } */ + "sit:Roadworks", + /* { */ "sit:MaintenanceWorks", + /* | */ "sit:ConstructionWorks", + /* } */ + "sit:Obstruction", + /* { */ "sit:EnvironmentalObstruction", + /* | */ "sit:GeneralObstruction", + /* | */ "sit:InfrastructureDamageObstruction", + /* } */ + "sit:Activity", + /* { */ "sit:PublicEvent", + /* } */ }; if (record_type == "sit:RoadOrCarriagewayOrLaneManagement") { - if (auto rc = handle_road_or_carriageway_or_lane_management( - record_xml, sit)) + if (auto rc = + handle_road_or_carriageway_or_lane_management(record_xml, sit)) { sit->road_closures.push_back(*rc); } @@ -335,10 +335,10 @@ public: // (comment_xml.child_value("sit:commentType") // == "internalNote"sv) { auto candidate = std::optional>{}; // (text, language) + std::string_view, std::string_view>>{}; // (text, language) for (auto const comment_value_xml : comment_xml.child("sit:comment") - .child("com:values") - .children("com:value")) + .child("com:values") + .children("com:value")) { if (!candidate || comment_value_xml.attribute("lang").value() == "nl"sv @@ -346,8 +346,8 @@ public: && comment_value_xml.attribute("lang").value() == "nl"sv)) { candidate = std::make_pair( - comment_value_xml.child_value(), - comment_value_xml.attribute("lang").value()); + comment_value_xml.child_value(), + comment_value_xml.attribute("lang").value()); } } if (candidate) @@ -355,7 +355,7 @@ public: auto already_present = false; for (auto const& comment : sit->comments) already_present = - already_present || comment == candidate->first; + already_present || comment == candidate->first; if (!already_present) { sit->comments.emplace_back(candidate->first); @@ -365,19 +365,19 @@ public: } if (auto const location_ref_xml = - record_xml.child("sit:locationReference")) + record_xml.child("sit:locationReference")) { if (location_ref_xml.attribute("xsi:type").value() == "loc:PointLocation"sv) { if (auto const coords_xml = - location_ref_xml.child("loc:pointByCoordinates") - .child("loc:pointCoordinates")) + location_ref_xml.child("loc:pointByCoordinates") + .child("loc:pointCoordinates")) { auto const mlat = - util::parse_double(coords_xml.child_value("loc:latitude")); + util::parse_double(coords_xml.child_value("loc:latitude")); auto const mlon = - util::parse_double(coords_xml.child_value("loc:longitude")); + util::parse_double(coords_xml.child_value("loc:longitude")); if (mlat && mlon) { // Vaag genoeg zegt NDW dat het hier om WGS @@ -404,8 +404,8 @@ public: } return { - .publication_time = *mpublication_time, - .situations = situations, + .publication_time = *mpublication_time, + .situations = situations, }; } diff --git a/server/src/geo.cppm b/server/src/geo.cppm index b599ad4..9101af8 100644 --- a/server/src/geo.cppm +++ b/server/src/geo.cppm @@ -9,15 +9,15 @@ export namespace bgeo = boost::geometry; export namespace routemon::geo { using point = - bgeo::model::point>; + bgeo::model::point>; using linestring = bgeo::model::linestring; using box = bgeo::model::box; using stype = bgeo::srs::spheroid; using vincenty_strategy = bgeo::strategy::distance::vincenty; auto split_linestring_with_overlap_segments( - linestring const& ls, double max_split_distance_m, - std::vector& append_to) -> void + linestring const& ls, double max_split_distance_m, + std::vector& append_to) -> void { if (bgeo::is_empty(ls)) return; @@ -26,23 +26,23 @@ auto split_linestring_with_overlap_segments( auto current_ls_length = 0.0; auto previous = std::optional{}; bgeo::for_each_point( - ls, - [&](point p) -> void + ls, + [&](point p) -> void + { + bgeo::append(current_ls, p); + if (previous) { - bgeo::append(current_ls, p); - if (previous) + auto d = bgeo::distance(*previous, p, vincenty_strategy()); + current_ls_length += d; + if (current_ls_length > max_split_distance_m) { - auto d = bgeo::distance(*previous, p, vincenty_strategy()); - current_ls_length += d; - if (current_ls_length > max_split_distance_m) - { - append_to.push_back(std::move(current_ls)); - current_ls = linestring{*previous, p}; - current_ls_length = d; - } + append_to.push_back(std::move(current_ls)); + current_ls = linestring{*previous, p}; + current_ls_length = d; } - previous = p; - }); + } + previous = p; + }); append_to.emplace_back(std::move(current_ls)); } diff --git a/server/src/gpx.cpp b/server/src/gpx.cpp index 44a6bb2..f70c133 100644 --- a/server/src/gpx.cpp +++ b/server/src/gpx.cpp @@ -22,7 +22,7 @@ auto qname(std::string_view local) -> xml::qname_view } auto parse_wpt(xml::executor_ref e, xml::attribute_view attrs) - -> xml::parser + -> xml::parser { auto parse_xml_double = [](std::string_view sv) -> std::optional { return util::parse_double(sv, std::chars_format::fixed); }; @@ -41,18 +41,18 @@ auto parse_wpt(xml::executor_ref e, xml::attribute_view attrs) } if (!mlat || !mlon) throw std::runtime_error{ - "expected valid latitude and longitude for waypoint" + "expected valid latitude and longitude for waypoint" }; co_await xml::ignore_contents(e); co_return geo::point{*mlon, *mlat}; } auto parse_trkseg(xml::executor_ref e, xml::attribute_view) - -> xml::parser + -> xml::parser { auto s = track_segment{}; - while (auto mwpt = co_await allow_element( - e, qname("trkpt"), xml::hohalo())) + while (auto mwpt = + co_await allow_element(e, qname("trkpt"), xml::hohalo())) bgeo::append(s.waypoints, *mwpt); co_return std::move(s); } @@ -61,20 +61,20 @@ auto parse_trk(xml::executor_ref e, xml::attribute_view) -> xml::parser { auto t = track{}; t.name = co_await allow_element( - e, qname("name"), xml::hohalo()); + e, qname("name"), xml::hohalo()); co_await allow_element( - e, qname("cmt"), xml::hohalo()); + e, qname("cmt"), xml::hohalo()); t.desc = co_await allow_element( - e, qname("desc"), xml::hohalo()); + e, qname("desc"), xml::hohalo()); co_await xml::ignore_contents(e, /* until */ qname("trkseg")); while (auto mseg = co_await allow_element( - e, qname("trkseg"), xml::hohalo())) + e, qname("trkseg"), xml::hohalo())) t.segments.push_back(std::move(*mseg)); co_return std::move(t); } auto parse_gpx(xml::executor_ref e, xml::attribute_view attrs) - -> xml::parser + -> xml::parser { auto f = file{}; if (attrs.lookup(qname("version")) != "1.0"sv) @@ -85,13 +85,13 @@ auto parse_gpx(xml::executor_ref e, xml::attribute_view attrs) throw std::runtime_error{"expected GPX file to have creator"}; f.meta.name = co_await allow_element( - e, qname("name"), xml::hohalo()); + e, qname("name"), xml::hohalo()); f.meta.desc = co_await allow_element( - e, qname("desc"), xml::hohalo()); + e, qname("desc"), xml::hohalo()); co_await xml::ignore_contents(e, /* until */ qname("trk")); while (auto mtrk = - co_await allow_element(e, qname("trk"), xml::hohalo())) + co_await allow_element(e, qname("trk"), xml::hohalo())) f.tracks.push_back(std::move(*mtrk)); co_await xml::ignore_contents(e); @@ -109,19 +109,19 @@ auto qname(std::string_view local) -> xml::qname_view } auto parse_metadata(xml::executor_ref e, xml::attribute_view) - -> xml::parser + -> xml::parser { auto meta = metadata{}; meta.name = co_await allow_element( - e, qname("name"), xml::hohalo()); + e, qname("name"), xml::hohalo()); meta.desc = co_await allow_element( - e, qname("desc"), xml::hohalo()); + e, qname("desc"), xml::hohalo()); co_await xml::ignore_contents(e); co_return meta; } auto parse_wpt(xml::executor_ref e, xml::attribute_view attrs) - -> xml::parser + -> xml::parser { auto parse_xml_double = [](std::string_view sv) -> std::optional { return util::parse_double(sv, std::chars_format::fixed); }; @@ -140,21 +140,21 @@ auto parse_wpt(xml::executor_ref e, xml::attribute_view attrs) } if (!mlat || !mlon) throw std::runtime_error{ - "expected valid latitude and longitude for waypoint" + "expected valid latitude and longitude for waypoint" }; co_await xml::ignore_contents(e); co_return geo::point{*mlon, *mlat}; } auto parse_trkseg(xml::executor_ref e, xml::attribute_view) - -> xml::parser + -> xml::parser { auto s = track_segment{}; - while (auto mwpt = co_await allow_element( - e, qname("trkpt"), xml::hohalo())) + while (auto mwpt = + co_await allow_element(e, qname("trkpt"), xml::hohalo())) bgeo::append(s.waypoints, *mwpt); co_await allow_element( - e, qname("extensions"), xml::hohalo()); + e, qname("extensions"), xml::hohalo()); co_return std::move(s); } @@ -162,20 +162,20 @@ auto parse_trk(xml::executor_ref e, xml::attribute_view) -> xml::parser { auto t = track{}; t.name = co_await allow_element( - e, qname("name"), xml::hohalo()); + e, qname("name"), xml::hohalo()); co_await allow_element( - e, qname("cmt"), xml::hohalo()); + e, qname("cmt"), xml::hohalo()); t.desc = co_await allow_element( - e, qname("desc"), xml::hohalo()); + e, qname("desc"), xml::hohalo()); co_await xml::ignore_contents(e, /* until */ qname("trkseg")); while (auto mseg = co_await allow_element( - e, qname("trkseg"), xml::hohalo())) + e, qname("trkseg"), xml::hohalo())) t.segments.push_back(std::move(*mseg)); co_return std::move(t); } auto parse_gpx(xml::executor_ref e, xml::attribute_view attrs) - -> xml::parser + -> xml::parser { auto f = file{}; if (attrs.lookup(qname("version")) != "1.1"sv) @@ -186,14 +186,14 @@ auto parse_gpx(xml::executor_ref e, xml::attribute_view attrs) throw std::runtime_error{"expected GPX file to have creator"}; if (auto mmeta = co_await allow_element( - e, qname("metadata"), xml::hohalo())) + e, qname("metadata"), xml::hohalo())) f.meta = *mmeta; co_await xml::ignore_contents(e, /* until */ qname("trk")); while (auto mtrk = - co_await allow_element(e, qname("trk"), xml::hohalo())) + co_await allow_element(e, qname("trk"), xml::hohalo())) f.tracks.push_back(std::move(*mtrk)); co_await allow_element( - e, qname("extensions"), xml::hohalo()); + e, qname("extensions"), xml::hohalo()); co_return std::move(f); } @@ -205,14 +205,14 @@ auto parse_file(xml::executor_ref e) -> xml::parser auto decl = co_await expect_event(e); if (decl.version != "1.0"sv) throw std::runtime_error{std::format( - "unsupported XML version, got {}", std::string_view{decl.version})}; + "unsupported XML version, got {}", std::string_view{decl.version})}; if (decl.encoding != "UTF-8"sv) throw std::runtime_error{"unsupported encoding"}; if (auto mf = co_await allow_element( - e, v10::qname("gpx"), xml::hohalo())) + e, v10::qname("gpx"), xml::hohalo())) co_return std::move(*mf); if (auto mf = co_await allow_element( - e, v11::qname("gpx"), xml::hohalo())) + e, v11::qname("gpx"), xml::hohalo())) co_return std::move(*mf); throw std::runtime_error{"no supported GPX document found"}; } diff --git a/server/src/http_client.cppm b/server/src/http_client.cppm index bea5384..13dd60a 100644 --- a/server/src/http_client.cppm +++ b/server/src/http_client.cppm @@ -27,12 +27,12 @@ public: { sslc_.set_default_verify_paths(); sslc_.set_verify_mode( - net::ssl::verify_peer | net::ssl::verify_fail_if_no_peer_cert); + net::ssl::verify_peer | net::ssl::verify_fail_if_no_peer_cert); } template auto do_request(bhttp::request& req) - -> bhttp::response + -> bhttp::response { auto stream = ssl::stream{ioc_, sslc_}; @@ -40,7 +40,7 @@ public: if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) { throw beast::system_error( - static_cast(::ERR_get_error()), net::error::get_ssl_category()); + static_cast(::ERR_get_error()), net::error::get_ssl_category()); } stream.set_verify_callback(ssl::host_name_verification(host)); auto const results = resolver_.resolve(host, "443"); diff --git a/server/src/http_server.cppm b/server/src/http_server.cppm index 0f7fda7..366037f 100644 --- a/server/src/http_server.cppm +++ b/server/src/http_server.cppm @@ -41,7 +41,7 @@ private: virtual ~impl_base() = default; virtual auto header() -> bhttp::response_header& = 0; virtual auto header() const - -> bhttp::response_header const& = 0; + -> bhttp::response_header const& = 0; virtual auto is_done() const -> bool = 0; virtual auto prepare(beast::error_code&) -> const_buffers_type = 0; virtual auto consume(std::size_t n) -> void = 0; @@ -121,12 +121,12 @@ private: auto keep_alive() const noexcept -> bool override { return state_.visit( - util::overloaded{ - [](bhttp::response const& rsp) -> bool - { return rsp.keep_alive(); }, - [](bhttp::message_generator const& gen) -> bool - { return gen.keep_alive(); }, - }); + util::overloaded{ + [](bhttp::response const& rsp) -> bool + { return rsp.keep_alive(); }, + [](bhttp::message_generator const& gen) -> bool + { return gen.keep_alive(); }, + }); } }; @@ -164,15 +164,15 @@ using next_handler_t = std::functionnet::awaitable>; template using middleware_t = - std::function&, - next_handler_t) - ->net::awaitable>; + std::function&, + next_handler_t) + ->net::awaitable>; template auto lax_cors_middleware( - Ctx ctx, bhttp::request_header& req_hdr, - next_handler_t next) -> net::awaitable + Ctx ctx, bhttp::request_header& req_hdr, + next_handler_t next) -> net::awaitable { std::ignore = req_hdr; auto prersp = co_await next(ctx); @@ -188,16 +188,16 @@ struct trace_id_ctx : InnerCtx template auto trace_id_middleware( - OuterCtx ctx0, bhttp::request_header& req_hdr, - next_handler_t> next) -> net::awaitable + OuterCtx ctx0, bhttp::request_header& req_hdr, + next_handler_t> next) -> net::awaitable { std::ignore = req_hdr; auto ctx = trace_id_ctx{std::move(ctx0)}; auto prersp = co_await next(std::move(ctx)); prersp.header().set( - "X-Routemon-Trace-Id", std::string_view{ctx.trace_id.as_string()}); + "X-Routemon-Trace-Id", std::string_view{ctx.trace_id.as_string()}); prersp.header().insert( - bhttp::field::access_control_expose_headers, "X-Routemon-Trace-Id"); + bhttp::field::access_control_expose_headers, "X-Routemon-Trace-Id"); co_return std::move(prersp); } @@ -208,8 +208,8 @@ struct base_ctx template using basic_route_handler_fn_t = std::function< - auto(Ctx, readable_request, std::vector const& matches) - ->net::awaitable>; + auto(Ctx, readable_request, std::vector const& matches) + ->net::awaitable>; struct keep_alive { @@ -228,8 +228,8 @@ auto make_rsp(bhttp::status status, keep_alive ka) -> bhttp::response } auto problem_rsp( - base_ctx const& ctx, problem::details const& problem, keep_alive ka) - -> presponse + base_ctx const& ctx, problem::details const& problem, keep_alive ka) + -> presponse { auto rsp = make_rsp(problem.status, ka); rsp.set(bhttp::field::content_type, "application/problem+json"); @@ -244,18 +244,17 @@ struct preflight_response std::vector allow_headers; }; auto make_preflight_rsp(preflight_response res, keep_alive ka) - -> bhttp::response + -> bhttp::response { auto rsp = make_rsp(bhttp::status::no_content, ka); auto allow_headers_str = res.allow_headers | std::views::transform( - [](auto const& field) -> std::string_view - { return bhttp::to_string(field); }) + [](auto const& field) -> std::string_view + { return bhttp::to_string(field); }) | std::views::join_with(std::string_view{", "}) | std::ranges::to(); rsp.set( - bhttp::field::access_control_allow_methods, - res.allow_methods.to_string()); + bhttp::field::access_control_allow_methods, res.allow_methods.to_string()); rsp.set(bhttp::field::access_control_allow_headers, allow_headers_str); rsp.prepare_payload(); return rsp; @@ -266,7 +265,7 @@ auto make_preflight_rsp(preflight_response res, keep_alive ka) // anyway, but all context types should derive from base_ctx). template auto read_request(base_ctx const& ctx, readable_request&& r) - -> net::awaitable, presponse>> + -> net::awaitable, presponse>> { std::ignore = ctx; auto p = bhttp::request_parser{std::move(*r.p)}; @@ -276,20 +275,19 @@ auto read_request(base_ctx const& ctx, readable_request&& r) template <> auto read_request(base_ctx const& ctx, readable_request&& r) - -> net::awaitable< - std::expected, presponse>> + -> net::awaitable, presponse>> { auto [ec, _] = - co_await bhttp::async_read(*r.strm, *r.buf, *r.p, net::as_tuple); + co_await bhttp::async_read(*r.strm, *r.buf, *r.p, net::as_tuple); if (ec == bhttp::error::unexpected_body) { auto tpl = problem::tpl{ - .status = bhttp::status::bad_request, - .title = translate("No body expected for this request"), - .type_uri = "https://routemon.fautchen.eu/problems/unexpected-body", + .status = bhttp::status::bad_request, + .title = translate("No body expected for this request"), + .type_uri = "https://routemon.fautchen.eu/problems/unexpected-body", }; co_return std::unexpected{problem_rsp( - ctx, tpl.instantiate(), keep_alive{false})}; + ctx, tpl.instantiate(), keep_alive{false})}; } else if (ec) { @@ -310,8 +308,8 @@ template [](routed_ctx const&) {}(ctx); } auto default_options_handler( - Ctx const& ctx, readable_request r, std::vector const&) - -> net::awaitable + Ctx const& ctx, readable_request r, std::vector const&) + -> net::awaitable { auto mreq = co_await read_request(ctx, std::move(r)); if (!mreq) @@ -321,18 +319,18 @@ auto default_options_handler( { // CORS preflight request co_return make_preflight_rsp( - preflight_response{ - // TODO: should access-control-allow-methods contain OPTIONS? - .allow_methods = ctx.route_methods, - .allow_headers = {bhttp::field::content_type}, - }, - keep_alive{mreq->keep_alive()}); + preflight_response{ + // TODO: should access-control-allow-methods contain OPTIONS? + .allow_methods = ctx.route_methods, + .allow_headers = {bhttp::field::content_type}, + }, + keep_alive{mreq->keep_alive()}); } else { // Normal OPTIONS request auto rsp = make_rsp( - bhttp::status::no_content, keep_alive{mreq->keep_alive()}); + bhttp::status::no_content, keep_alive{mreq->keep_alive()}); rsp.set(bhttp::field::allow, ctx.route_methods.to_string()); rsp.prepare_payload(); co_return std::move(rsp); @@ -340,7 +338,7 @@ auto default_options_handler( } auto global_options_handler(base_ctx const& ctx, readable_request r) - -> net::awaitable + -> net::awaitable { // TODO: switch to "small (4KB) discarded" body type, similar to what Go // does? Same goes for default_options_handler? Not sure. @@ -349,46 +347,45 @@ auto global_options_handler(base_ctx const& ctx, readable_request r) co_return std::move(res.error()); auto req = r.p->release(); auto rsp = make_rsp( - bhttp::status::no_content, keep_alive{req.keep_alive()}); + bhttp::status::no_content, keep_alive{req.keep_alive()}); rsp.prepare_payload(); co_return std::move(rsp); } template auto id_middleware( - Ctx ctx, bhttp::request_header&, next_handler_t next) - -> net::awaitable + Ctx ctx, bhttp::request_header&, next_handler_t next) + -> net::awaitable { co_return co_await next(std::move(ctx)); } template auto middleware_compose(middleware_t ab, middleware_t bc) - -> middleware_t + -> middleware_t { return [ab = std::move(ab), bc = std::move(bc)]( - A a, bhttp::request_header& header, - next_handler_t next) -> net::awaitable + A a, bhttp::request_header& header, + next_handler_t next) -> net::awaitable { co_return co_await ab( - std::move(a), header, [&](B b) -> net::awaitable - { co_return co_await bc(std::move(b), header, next); }); + std::move(a), header, [&](B b) -> net::awaitable + { co_return co_await bc(std::move(b), header, next); }); }; } template auto middleware_wrap_fn(middleware_t ab, basic_route_handler_fn_t fn) - -> basic_route_handler_fn_t + -> basic_route_handler_fn_t { - return - [ab = std::move(ab), fn = std::move(fn)]( - A a_ctx, readable_request r, - std::vector const& matches) -> net::awaitable + return [ab = std::move(ab), fn = std::move(fn)]( + A a_ctx, readable_request r, + std::vector const& matches) -> net::awaitable { co_return co_await ab( - std::move(a_ctx), r.p->get().base(), - [&](B b_ctx) -> net::awaitable - { co_return co_await fn(std::move(b_ctx), r, matches); }); + std::move(a_ctx), r.p->get().base(), + [&](B b_ctx) -> net::awaitable + { co_return co_await fn(std::move(b_ctx), r, matches); }); }; } @@ -448,15 +445,15 @@ struct handler_map template auto map(std::invocable auto f) const -> handler_map requires std::assignable_from< - U&, std::invoke_result_t> + U&, std::invoke_result_t> { return { - .options = static_cast(options) ? f(options) : U{}, - .delete_ = static_cast(delete_) ? f(delete_) : U{}, - .get = static_cast(get) ? f(get) : U{}, - .head = static_cast(head) ? f(head) : U{}, - .post = static_cast(post) ? f(post) : U{}, - .put = static_cast(put) ? f(put) : U{}, + .options = static_cast(options) ? f(options) : U{}, + .delete_ = static_cast(delete_) ? f(delete_) : U{}, + .get = static_cast(get) ? f(get) : U{}, + .head = static_cast(head) ? f(head) : U{}, + .post = static_cast(post) ? f(post) : U{}, + .put = static_cast(put) ? f(put) : U{}, }; } }; @@ -478,29 +475,29 @@ struct route_tree template auto middleware_wrap_tree( - middleware_t mw, route_tree const& tree) - -> route_tree + middleware_t mw, route_tree const& tree) + -> route_tree { auto new_leaves = tree.here.template map>( - std::bind_front(middleware_wrap_fn, mw)); + std::bind_front(middleware_wrap_fn, mw)); auto new_sub = tree.sub.visit( - util::overloaded{ - [&mw](route_tree::named_subtrees const& subtrees) - -> decltype(route_tree::sub) - { - auto new_subtrees = typename route_tree::named_subtrees{}; - for (auto [seg, subtree] : subtrees) - new_subtrees[seg] = middleware_wrap_tree(mw, subtree); - return new_subtrees; - }, - [&mw](route_tree::wildcard_subtree const& subtree) - -> decltype(route_tree::sub) - { - return typename route_tree::wildcard_subtree{ - middleware_wrap_tree(mw, *subtree) - }; - }, - }); + util::overloaded{ + [&mw](route_tree::named_subtrees const& subtrees) + -> decltype(route_tree::sub) + { + auto new_subtrees = typename route_tree::named_subtrees{}; + for (auto [seg, subtree] : subtrees) + new_subtrees[seg] = middleware_wrap_tree(mw, subtree); + return new_subtrees; + }, + [&mw](route_tree::wildcard_subtree const& subtree) + -> decltype(route_tree::sub) + { + return typename route_tree::wildcard_subtree{ + middleware_wrap_tree(mw, *subtree) + }; + }, + }); return {.here = new_leaves, .sub = new_sub}; } @@ -509,23 +506,21 @@ concept match_arg = std::constructible_from; template using route_handler_fn_t = std::function< - auto(Ctx, readable_request, MatchArgs...)->net::awaitable>; + auto(Ctx, readable_request, MatchArgs...)->net::awaitable>; template auto degen_route_handler(route_handler_fn_t fn) - -> basic_route_handler_fn_t + -> basic_route_handler_fn_t { - return - [fn = std::move(fn)]( - Ctx ctx, readable_request r, - std::vector const& matches) -> net::awaitable + return [fn = std::move(fn)]( + Ctx ctx, readable_request r, + std::vector const& matches) -> net::awaitable { if (sizeof...(MatchArgs) != matches.size()) throw std::runtime_error{"got unexpected amount of matches"}; auto it = matches.begin(); co_return co_await fn( - std::move(ctx), r, - MatchArgs{static_cast(*it++)}...); + std::move(ctx), r, MatchArgs{static_cast(*it++)}...); }; } @@ -534,7 +529,7 @@ struct ctree : route_tree { template auto wrap(middleware_t mw) const - -> ctree + -> ctree { return {middleware_wrap_tree(std::move(mw), *this)}; } @@ -546,25 +541,24 @@ struct dtree : handler_map> [[nodiscard]] auto to_leaves() const -> typename route_tree::leaves { auto here = this->template map>( - degen_route_handler); + degen_route_handler); if (!here.verbs().empty() && !static_cast(this->options)) here.options = default_options_handler; return here; } [[nodiscard]] auto named_subtrees( - std::initializer_list>> - subtrees) const -> ctree + std::initializer_list>> + subtrees) const -> ctree { auto sub = typename route_tree::named_subtrees{ - std::from_range, subtrees - | std::views::transform( - [](auto const& p) - { - return std::make_pair( - p.first, - static_cast>(p.second)); - }) + std::from_range, subtrees + | std::views::transform( + [](auto const& p) + { + return std::make_pair( + p.first, static_cast>(p.second)); + }) }; return {route_tree{.here = to_leaves(), .sub = sub}}; } @@ -572,13 +566,13 @@ struct dtree : handler_map> template [[nodiscard]] auto wildcard_subtree(ctree subtree) - -> ctree + -> ctree { return {route_tree{ - .here = to_leaves(), - .sub = typename route_tree::wildcard_subtree{ - static_cast>(subtree) - } + .here = to_leaves(), + .sub = typename route_tree::wildcard_subtree{ + static_cast>(subtree) + } }}; } @@ -598,9 +592,9 @@ class server public: explicit server( - log::logger const& l, locale::selector&& lsel, - middleware_t global_middleware, - route_tree> routes) + log::logger const& l, locale::selector&& lsel, + middleware_t global_middleware, + route_tree> routes) : l_{l.sub("http_server")}, lsel_{std::move(lsel)}, global_middleware_{std::move(global_middleware)}, routes_{std::move(routes)} @@ -610,55 +604,56 @@ public: struct match_result { util::not_null< - handler_map>> const*> - route_handlers; + handler_map>> const*> + route_handlers; std::vector wildcard_matches; auto allowed_methods() const -> verb_set { return route_handlers->verbs(); } }; auto match(boost::urls::segments_view segments) const - -> std::optional + -> std::optional { auto const* tree = &routes_; auto wildcard_matches = std::vector{}; for (auto const& seg : segments) { tree->sub.visit( - util::overloaded{ - [&](route_tree>::named_subtrees const& - subtrees) - { - auto it = subtrees.find(seg); - tree = it == subtrees.end() ? nullptr : &it->second; - }, - [&](route_tree>::wildcard_subtree const& - wildcard_subtree) - { - wildcard_matches.push_back(seg); - tree = &*wildcard_subtree; - }, - }); + util::overloaded{ + [&]( + route_tree>::named_subtrees const& subtrees) + { + auto it = subtrees.find(seg); + tree = it == subtrees.end() ? nullptr : &it->second; + }, + [&]( + route_tree>::wildcard_subtree const& + wildcard_subtree) + { + wildcard_matches.push_back(seg); + tree = &*wildcard_subtree; + }, + }); if (!tree) return std::nullopt; } if (tree->here.empty()) return std::nullopt; return match_result{ - .route_handlers = util::not_null{&tree->here}, - .wildcard_matches = wildcard_matches, + .route_handlers = util::not_null{&tree->here}, + .wildcard_matches = wildcard_matches, }; } auto route_request(PreRouteCtx ctx, readable_request r) const - -> net::awaitable + -> net::awaitable { auto req_base = r.p->get().base(); auto const bad_request_tpl = problem::tpl{ - .status = bhttp::status::bad_request, - .title = translate("Bad request"), - .type_uri = "https://routemon.fautchen.eu/problems/bad-request", + .status = bhttp::status::bad_request, + .title = translate("Bad request"), + .type_uri = "https://routemon.fautchen.eu/problems/bad-request", }; if (req_base.target() == "*") @@ -669,10 +664,10 @@ public: if (req_base.method() != bhttp::verb::options) { auto tpl = problem::tpl{ - .status = bhttp::status::method_not_allowed, - .title = translate("Method not allowed"), - .type_uri = "https://routemon.fautchen.eu/problems/" - "method-not-allowed", + .status = bhttp::status::method_not_allowed, + .title = translate("Method not allowed"), + .type_uri = "https://routemon.fautchen.eu/problems/" + "method-not-allowed", }; co_return problem_rsp(ctx, tpl.instantiate(), keep_alive{false}); } @@ -690,10 +685,10 @@ public: if (!req_url.is_path_absolute()) { auto problem = bad_request_tpl.instantiate().set_detail(translate( - "Path of normalized (RFC 3986, § 6) " - "origin-form request-target (RFC " - "9112, § 3.2.1) should be " - "absolute")); + "Path of normalized (RFC 3986, § 6) " + "origin-form request-target (RFC " + "9112, § 3.2.1) should be " + "absolute")); co_return problem_rsp(ctx, problem, keep_alive{false}); } @@ -701,9 +696,9 @@ public: if (!mres) { auto tpl = problem::tpl{ - .status = bhttp::status::not_found, - .title = translate("Not found"), - .type_uri = "https://routemon.fautchen.eu/problems/not-found", + .status = bhttp::status::not_found, + .title = translate("Not found"), + .type_uri = "https://routemon.fautchen.eu/problems/not-found", }; co_return problem_rsp(ctx, tpl.instantiate(), keep_alive{false}); } @@ -713,10 +708,10 @@ public: { // Method not implemented. auto tpl = problem::tpl{ - .status = bhttp::status::not_implemented, - .title = translate("Method not implemented"), - .type_uri = "https://routemon.fautchen.eu/problems/" - "method-not-implemented", + .status = bhttp::status::not_implemented, + .title = translate("Method not implemented"), + .type_uri = "https://routemon.fautchen.eu/problems/" + "method-not-implemented", }; co_return problem_rsp(ctx, tpl.instantiate(), keep_alive{false}); } @@ -724,21 +719,21 @@ public: if (auto mhdl = mres->route_handlers->lookup(*mverb)) { auto new_ctx = - routed_ctx{std::move(ctx), mres->allowed_methods()}; + routed_ctx{std::move(ctx), mres->allowed_methods()}; co_return co_await mhdl(std::move(new_ctx), r, mres->wildcard_matches); } else { // Path recognized, but method not allowed. auto tpl = problem::tpl{ - .status = bhttp::status::method_not_allowed, - .title = translate("Method not allowed"), - .type_uri = "https://routemon.fautchen.eu/problems/" - "method-not-allowed", + .status = bhttp::status::method_not_allowed, + .title = translate("Method not allowed"), + .type_uri = "https://routemon.fautchen.eu/problems/" + "method-not-allowed", }; auto rsp = problem_rsp(ctx, tpl.instantiate(), keep_alive{false}); rsp.header().set( - bhttp::field::allow, mres->allowed_methods().to_string()); + bhttp::field::allow, mres->allowed_methods().to_string()); co_return std::move(rsp); } } @@ -747,9 +742,9 @@ public: // We do not accept any other request-target forms. auto problem = bad_request_tpl.instantiate().set_detail(translate( - "Invalid request-target, expected " - "asterisk-form or origin-form " - "(see RFC 9112, § 3.2)")); + "Invalid request-target, expected " + "asterisk-form or origin-form " + "(see RFC 9112, § 3.2)")); co_return problem_rsp(ctx, problem, keep_alive{false}); } } @@ -761,9 +756,8 @@ public: auto ctx0 = base_ctx{.locale = locale}; co_return co_await global_middleware_( - std::move(ctx0), header, - [&](PreRouteCtx ctx) -> net::awaitable - { co_return co_await route_request(std::move(ctx), std::move(r)); }); + std::move(ctx0), header, [&](PreRouteCtx ctx) -> net::awaitable + { co_return co_await route_request(std::move(ctx), std::move(r)); }); } auto do_session(beast::tcp_stream strm) -> net::awaitable @@ -775,7 +769,7 @@ public: auto p0 = bhttp::request_parser{}; p0.body_limit(boost::none); auto [ec, _] = - co_await bhttp::async_read_header(strm, buf, p0, net::as_tuple); + co_await bhttp::async_read_header(strm, buf, p0, net::as_tuple); if (ec == bhttp::error::end_of_stream) break; else if (ec) @@ -783,11 +777,11 @@ public: auto http_version = p0.get().version(); auto&& rsp = co_await handle_request( - readable_request{ - .p = util::not_null{&p0}, - .strm = util::not_null{&strm}, - .buf = util::not_null{&buf}, - }); + readable_request{ + .p = util::not_null{&p0}, + .strm = util::not_null{&strm}, + .buf = util::not_null{&buf}, + }); rsp.header().version(http_version); bool keep_alive = rsp.keep_alive(); co_await beast::async_write(strm, std::move(rsp)); @@ -806,27 +800,27 @@ public: auto acceptor = tcp::acceptor{executor, endpoint}; l_.with("endpoint", endpoint.address().to_string()) - .with("port", std::to_string(endpoint.port())) - .info("Serving"); + .with("port", std::to_string(endpoint.port())) + .info("Serving"); while (true) { net::co_spawn( - executor, - do_session(beast::tcp_stream{co_await acceptor.async_accept()}), - [this](std::exception_ptr e) + executor, + do_session(beast::tcp_stream{co_await acceptor.async_accept()}), + [this](std::exception_ptr e) + { + if (e) { - if (e) + try + { + std::rethrow_exception(e); + } + catch (std::exception const& e) { - try - { - std::rethrow_exception(e); - } - catch (std::exception const& e) - { - l_.error("Error in session: {}", e.what()); - } + l_.error("Error in session: {}", e.what()); } - }); + } + }); } } @@ -837,21 +831,21 @@ public: // TODO: make exception handling as nice as in srv.cpp net::co_spawn( - ioc, do_listen(endpoint), - [this](std::exception_ptr e) + ioc, do_listen(endpoint), + [this](std::exception_ptr e) + { + if (e) { - if (e) + try { - try - { - std::rethrow_exception(e); - } - catch (std::exception const& e) - { - l_.error("Error: {}", e.what()); - } + std::rethrow_exception(e); } - }); + catch (std::exception const& e) + { + l_.error("Error: {}", e.what()); + } + } + }); } }; diff --git a/server/src/locale.cppm b/server/src/locale.cppm index 8fd867b..06607f0 100644 --- a/server/src/locale.cppm +++ b/server/src/locale.cppm @@ -50,11 +50,11 @@ struct icu_locale_hash }; using icu_locale_priority_map = - std::unordered_map; + std::unordered_map; using icu_priority_locale = std::pair; auto operator<(icu_priority_locale const& lhs, icu_priority_locale const& rhs) - -> bool + -> bool { return lhs.second < rhs.second; } @@ -66,7 +66,7 @@ class icu_priority_locale_vec_iterator : public icu::Locale::Iterator public: explicit icu_priority_locale_vec_iterator( - std::vector&& ls) + std::vector&& ls) : ls_(std::move(ls)) { } @@ -80,9 +80,8 @@ public: export template concept locale_input_range = - std::ranges::input_range - && std::same_as< - std::locale const&, std::ranges::range_const_reference_t>; + std::ranges::input_range + && std::same_as>; // Helps select a locale based on the Accept-Language header in an // HTTP request. @@ -93,23 +92,23 @@ export class selector std::shared_ptr lgen_; auto make_matcher( - locale_input_range auto supported_locales, std::locale default_locale) + locale_input_range auto supported_locales, std::locale default_locale) { auto builder = icu::LocaleMatcher::Builder{}; for (auto const& supported_locale : supported_locales) { auto const& supported_locale_info = - std::use_facet(supported_locale); + std::use_facet(supported_locale); auto supported_icu_locale = - icu::Locale{supported_locale_info.name().c_str()}; + icu::Locale{supported_locale_info.name().c_str()}; if (supported_icu_locale.isBogus()) throw std::runtime_error{ - "supported locale gives rise to bogus ICU locale" + "supported locale gives rise to bogus ICU locale" }; builder.addSupportedLocale(supported_icu_locale); } auto const& default_locale_info = - std::use_facet(default_locale); + std::use_facet(default_locale); auto default_icu_locale = icu::Locale{default_locale_info.name().c_str()}; if (default_icu_locale.isBogus()) throw std::runtime_error{"default locale gives rise to bogus ICU locale"}; @@ -171,7 +170,7 @@ export class selector while (kw = keywords->next(&kw_len, ec), !U_FAILURE(ec) && kw) { auto value = - l.getKeywordValue(icu::StringPiece(kw, kw_len), ec); + l.getKeywordValue(icu::StringPiece(kw, kw_len), ec); if (!added_at) { posix_name += "@"; @@ -196,8 +195,8 @@ public: // Note: lgen must live at least as long as the selector constructed here! // It is unfortunately not possible to copy/move a blocale::generator. explicit selector( - locale_input_range auto locales, std::locale default_, - std::shared_ptr lgen) + locale_input_range auto locales, std::locale default_, + std::shared_ptr lgen) : default_{default_}, matcher_{make_matcher(locales, default_)}, lgen_{lgen} { } @@ -212,7 +211,7 @@ public: accept_language | std::views::split(","sv) | std::views::enumerate) { auto [lang_range_ut, mweight_ut] = - util::split_on(std::string_view{lang_prio}, ';'); + util::split_on(std::string_view{lang_prio}, ';'); auto lang_range_str = trim_ows(lang_range_ut); auto mweight_str = mweight_ut.transform(trim_ows); if (lang_range_str == "*") @@ -228,7 +227,7 @@ public: { auto weight_str = mweight_str->substr(2, 4); if (auto mweight = - util::parse_float(weight_str, std::chars_format::fixed); + util::parse_float(weight_str, std::chars_format::fixed); mweight && 0.0f < *mweight && *mweight < 1.0f) { weight = *mweight; @@ -238,8 +237,8 @@ public: if (weight > 0.0f) { dlpm[icu_locale] = { - .weight = weight, - .original_index = static_cast(i), + .weight = weight, + .original_index = static_cast(i), }; } else @@ -249,7 +248,7 @@ public: } auto desired_locales = - std::vector{dlpm.begin(), dlpm.end()}; + std::vector{dlpm.begin(), dlpm.end()}; std::sort(desired_locales.begin(), desired_locales.end()); auto it = icu_priority_locale_vec_iterator{std::move(desired_locales)}; auto ec = UErrorCode::U_ZERO_ERROR; @@ -268,7 +267,7 @@ export auto to_bcp47_lang_tag(std::locale locale) -> std::optional auto const& locale_info = std::use_facet(locale); auto ec = UErrorCode::U_ZERO_ERROR; auto bcp47_lang_tag = - icu::Locale{locale_info.name().c_str()}.toLanguageTag(ec); + icu::Locale{locale_info.name().c_str()}.toLanguageTag(ec); if (U_FAILURE(ec)) return std::nullopt; return bcp47_lang_tag; diff --git a/server/src/log.cppm b/server/src/log.cppm index 0bfdf7d..7c42144 100644 --- a/server/src/log.cppm +++ b/server/src/log.cppm @@ -97,12 +97,12 @@ export class logger { if (sink_->level() <= lvl) sink_->write( - sink::tmp_message{ - .lvl = lvl, - .component = component_, - .txt = std::vformat(fmt, args), - .attrs = attrs_, - }); + sink::tmp_message{ + .lvl = lvl, + .component = component_, + .txt = std::vformat(fmt, args), + .attrs = attrs_, + }); return *this; } @@ -138,7 +138,7 @@ public: } [[nodiscard]] auto with(std::string const& k, std::string_view v) const - -> logger + -> logger { return with(k, std::string{v}); } diff --git a/server/src/main.cpp b/server/src/main.cpp index 0a7a784..2957808 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -21,9 +21,9 @@ auto real_main(std::span args) -> exit_status if (args.size() != 2) { l.error( - "Fatal: expected exactly one argument (the configuration file " - "location), got {}", - args.size() - 1); + "Fatal: expected exactly one argument (the configuration file " + "location), got {}", + args.size() - 1); return exit_status::bad_usage; } auto const* config_filename = args[1]; @@ -31,10 +31,10 @@ auto real_main(std::span args) -> exit_status auto lgen = routemon::locale::make_generator(); auto default_locale = lgen->generate("en_US.UTF-8"); auto locales = { - default_locale, - lgen->generate("nl_NL.UTF-8"), - lgen->generate("de_DE.UTF-8"), - lgen->generate("en_GB.UTF-8"), + default_locale, + lgen->generate("nl_NL.UTF-8"), + lgen->generate("de_DE.UTF-8"), + lgen->generate("en_GB.UTF-8"), }; auto lsel = routemon::locale::selector{locales, default_locale, lgen}; @@ -48,7 +48,7 @@ auto real_main(std::span args) -> exit_status catch (std::exception const& e) { l.with("filename", std::string_view{config_filename}) - .error("Failed to load configuration: {}", e.what()); + .error("Failed to load configuration: {}", e.what()); return exit_status::failure; } sink->set_level(config.logger.level); @@ -68,19 +68,19 @@ auto real_main(std::span args) -> exit_status catch (std::exception const& e) { l.with("filename", config.database.sqlite3_filename) - .error("Failed to open database: {}", e.what()); + .error("Failed to open database: {}", e.what()); return exit_status::failure; } l.with("filename", config.situations.datex2_filename) - .info("Loading situations"); + .info("Loading situations"); auto const before_load = chrono::steady_clock::now(); auto d2loader = routemon::datex2::loader{}; auto pub = routemon::datex2::situation_publication{}; try { pub = - d2loader.load_situation_publication(config.situations.datex2_filename); + d2loader.load_situation_publication(config.situations.datex2_filename); } catch (std::exception const& e) { @@ -91,9 +91,9 @@ auto real_main(std::span args) -> exit_status { auto const& warns = d2loader.warnings(); l.warn( - "Encountered {} unique warnings while loading DATEX II situations " - "publication", - warns.size()); + "Encountered {} unique warnings while loading DATEX II situations " + "publication", + warns.size()); auto i = 0uz; for (auto it = warns.begin(); it != warns.end(); it = warns.upper_bound(*it)) @@ -108,12 +108,12 @@ auto real_main(std::span args) -> exit_status malloc_trim(0); auto const after_load = chrono::steady_clock::now(); auto const dur_load = - chrono::duration_cast(after_load - before_load); + chrono::duration_cast(after_load - before_load); l.info("Loading situations finished in {}", dur_load); auto handler = routemon::api::handler{l, std::move(pub)}; auto http_server = - routemon::srv::server{l, std::move(lsel), std::move(handler)}; + routemon::srv::server{l, std::move(lsel), std::move(handler)}; http_server.spawn(ioc); ioc.run(); @@ -129,9 +129,7 @@ auto main(int argc, char* argv[]) -> int return EXIT_FAILURE; } auto res = real_main( - std::span{ - const_cast(argv), static_cast(argc) - }); + std::span{const_cast(argv), static_cast(argc)}); switch (res) { case exit_status::failure: diff --git a/server/src/problem.cppm b/server/src/problem.cppm index a124312..a72379a 100644 --- a/server/src/problem.cppm +++ b/server/src/problem.cppm @@ -41,13 +41,13 @@ export struct details }; export auto tag_invoke( - json::value_from_tag, json::value& jv, details const& details, - std::locale locale) -> void + json::value_from_tag, json::value& jv, details const& details, + std::locale locale) -> void { auto obj = json::object{ - {"type", details.type_uri}, - {"title", details.title.str(locale)}, - {"status", static_cast(details.status)}, + {"type", details.type_uri}, + {"title", details.title.str(locale)}, + {"status", static_cast(details.status)}, }; if (details.detail) obj["detail"] = details.detail->str(locale); diff --git a/server/src/req_ctx.cppm b/server/src/req_ctx.cppm index 4a64d7d..464f2ff 100644 --- a/server/src/req_ctx.cppm +++ b/server/src/req_ctx.cppm @@ -20,8 +20,8 @@ export class req_ctx public: explicit req_ctx( - trace::id tid, std::locale locale, http::verb_set route_verbs, - bool keep_alive, bhttp::request_header const& req_header) + trace::id tid, std::locale locale, http::verb_set route_verbs, + bool keep_alive, bhttp::request_header const& req_header) : tid_{tid}, locale_{locale}, route_verbs_{route_verbs}, keep_alive_{keep_alive}, req_header_{req_header} { @@ -29,8 +29,8 @@ public: template explicit req_ctx( - trace::id tid, std::locale locale, http::verb_set route_verbs, - bhttp::request const& req) + trace::id tid, std::locale locale, http::verb_set route_verbs, + bhttp::request const& req) : req_ctx{tid, locale, route_verbs, req.keep_alive(), req.base()} { } diff --git a/server/src/rwgps.cppm b/server/src/rwgps.cppm index 8269ee8..f2f1681 100644 --- a/server/src/rwgps.cppm +++ b/server/src/rwgps.cppm @@ -46,50 +46,50 @@ struct get_routes_response }; auto tag_invoke(json::value_to_tag const&, json::value const& jv) - -> route_summary + -> route_summary { return { - .id = json::value_to(jv.at("id")), - .user_id = json::value_to(jv.at("user_id")), - .url = json::value_to(jv.at("url")), - .name = json::value_to(jv.at("name")), - .description = json::value_to(jv.at("description")), + .id = json::value_to(jv.at("id")), + .user_id = json::value_to(jv.at("user_id")), + .url = json::value_to(jv.at("url")), + .name = json::value_to(jv.at("name")), + .description = json::value_to(jv.at("description")), }; } auto tag_invoke(json::value_to_tag const&, json::value const& jv) - -> pagination + -> pagination { return { - .record_count = json::value_to(jv.at("record_count")), - .page_count = json::value_to(jv.at("page_count")), - .page_size = json::value_to(jv.at("page_size")), - .next_page_url = - json::value_to>(jv.at("next_page_url")), + .record_count = json::value_to(jv.at("record_count")), + .page_count = json::value_to(jv.at("page_count")), + .page_size = json::value_to(jv.at("page_size")), + .next_page_url = + json::value_to>(jv.at("next_page_url")), }; } auto tag_invoke( - json::value_to_tag const&, json::value const& jv) - -> get_routes_meta + json::value_to_tag const&, json::value const& jv) + -> get_routes_meta { return { - .pagination = json::value_to(jv.at("pagination")), + .pagination = json::value_to(jv.at("pagination")), }; } auto tag_invoke( - json::value_to_tag const&, json::value const& jv) - -> get_routes_response + json::value_to_tag const&, json::value const& jv) + -> get_routes_response { return { - .routes = json::value_to>(jv.at("routes")), - .meta = json::value_to(jv.at("meta")), + .routes = json::value_to>(jv.at("routes")), + .meta = json::value_to(jv.at("meta")), }; } auto json_value_to_get_routes_response(json::value const& jv) - -> get_routes_response + -> get_routes_response { return json::value_to(jv); } @@ -107,9 +107,9 @@ export class client auto get_routes_page(std::size_t page) -> get_routes_response { auto req = bhttp::request{ - bhttp::verb::get, - std::format("/api/v1/routes.json?page_size=200?page={}", page), - 11, // HTTP 1.1 + bhttp::verb::get, + std::format("/api/v1/routes.json?page_size=200?page={}", page), + 11, // HTTP 1.1 }; req.set(bhttp::field::host, host); req.set("x-rwgps-api-key", api_key_); @@ -127,8 +127,8 @@ export class client public: explicit client( - net::io_context& ioc, log::logger const& l, std::string api_key, - std::string auth_token) + net::io_context& ioc, log::logger const& l, std::string api_key, + std::string auth_token) : l_{l.sub("rwgps-client")}, hc_{ioc}, api_key_{std::move(api_key)}, auth_token_{std::move(auth_token)} { diff --git a/server/src/sqlite3.cppm b/server/src/sqlite3.cppm index 70f58c0..45366b8 100644 --- a/server/src/sqlite3.cppm +++ b/server/src/sqlite3.cppm @@ -18,7 +18,7 @@ class mutex_guard friend auto do_guarded(::sqlite3_mutex* mut, std::invocable auto f) - -> decltype(f(std::declval())); + -> decltype(f(std::declval())); public: mutex_guard(mutex_guard const&) = delete; @@ -29,13 +29,13 @@ private: }; auto do_guarded(::sqlite3_mutex* mut, std::invocable auto f) - -> decltype(f(std::declval())) + -> decltype(f(std::declval())) { return f(mutex_guard{mut}); } auto do_guarded(::sqlite3* dbc, std::invocable auto f) - -> decltype(f(std::declval())) + -> decltype(f(std::declval())) { return do_guarded(::sqlite3_db_mutex(dbc), f); } @@ -143,16 +143,16 @@ public: { ::sqlite3* dbc = ::sqlite3_db_handle(stmt_.get()); return do_guarded( - dbc, - [&](auto const& guard) -> bool - { - auto const s = ::sqlite3_step(stmt_.get()); - if (s == SQLITE_ROW) - return true; - if (s == SQLITE_DONE) - return false; - throw error{guard, s, dbc}; - }); + dbc, + [&](auto const& guard) -> bool + { + auto const s = ::sqlite3_step(stmt_.get()); + if (s == SQLITE_ROW) + return true; + if (s == SQLITE_DONE) + return false; + throw error{guard, s, dbc}; + }); } auto scan(scannable auto&... args) -> void @@ -162,7 +162,7 @@ public: throw std::logic_error{"got unexpected negative amount of columns"}; if (sizeof...(args) > *ncols) throw std::invalid_argument{ - "more scanning arguments provided than columns in result set" + "more scanning arguments provided than columns in result set" }; auto col = 0; (..., scan(col++, args)); @@ -192,15 +192,15 @@ public: auto text(std::string const& param_name, std::string_view str) -> void { int const i = - ::sqlite3_bind_parameter_index(stmt_.get(), param_name.c_str()); + ::sqlite3_bind_parameter_index(stmt_.get(), param_name.c_str()); if (i == 0) throw std::invalid_argument{std::format( - "bind: no parameter with name {} found", param_name)}; + "bind: no parameter with name {} found", param_name)}; auto str_size = util::int_from_size(str.size()); if (!str_size.has_value()) throw std::invalid_argument{"bind: provided text is too long"}; if (auto s = ::sqlite3_bind_text( - stmt_.get(), i, str.data(), *str_size, SQLITE_TRANSIENT); + stmt_.get(), i, str.data(), *str_size, SQLITE_TRANSIENT); s != SQLITE_OK) { throw error{s}; @@ -232,8 +232,8 @@ public: } [[nodiscard]] auto query( - std::string const& sql, - std::function const& bf = binder::noop) -> row_reader + std::string const& sql, + std::function const& bf = binder::noop) -> row_reader { ::sqlite3_stmt* pstmt = nullptr; char const* sql_tail = nullptr; @@ -242,31 +242,31 @@ public: || *sql_size >= std::numeric_limits::max() - 1) throw std::invalid_argument{"provided input text too large"}; do_guarded( - mut_, - [&](auto const& guard) -> void + mut_, + [&](auto const& guard) -> void + { + if (auto s = ::sqlite3_prepare_v2( + dbc_, sql.data(), *sql_size + 1, &pstmt, &sql_tail); + s != SQLITE_OK) { - if (auto s = ::sqlite3_prepare_v2( - dbc_, sql.data(), *sql_size + 1, &pstmt, &sql_tail); - s != SQLITE_OK) + if (pstmt != nullptr) { - if (pstmt != nullptr) - { - // Use contract_assert when having a compiler with - // contracts available - ::sqlite3_finalize(pstmt); - throw std::logic_error{ - "expected stmt to be null after failed preparation" - }; - } - throw error{guard, s, dbc_}; + // Use contract_assert when having a compiler with + // contracts available + ::sqlite3_finalize(pstmt); + throw std::logic_error{ + "expected stmt to be null after failed preparation" + }; } - }); + throw error{guard, s, dbc_}; + } + }); if (!pstmt) throw std::invalid_argument{"provided input text contains no SQL"}; auto stmt = statement{pstmt}; if (sql_tail && std::strlen(sql_tail) > 0) throw std::invalid_argument{ - "provided input text contains more than one SQL statement" + "provided input text contains more than one SQL statement" }; auto b = binder{stmt}; bf(b); @@ -274,8 +274,8 @@ public: } auto exec( - std::string const& sql, - std::function const& bf = binder::noop) -> void + std::string const& sql, + std::function const& bf = binder::noop) -> void { auto reader = query(sql, bf); while (reader.next()) @@ -289,16 +289,16 @@ export auto open(std::string const& filename) -> connection { ::sqlite3* dbc = nullptr; auto s = ::sqlite3_open_v2( - filename.c_str(), &dbc, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX - | SQLITE_OPEN_EXRESCODE, - nullptr); + filename.c_str(), &dbc, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX + | SQLITE_OPEN_EXRESCODE, + nullptr); if (s != SQLITE_OK) { if (dbc) { do_guarded( - dbc, [&](auto const& guard) -> void { throw error{guard, s, dbc}; }); + dbc, [&](auto const& guard) -> void { throw error{guard, s, dbc}; }); } else { diff --git a/server/src/srv.cppm b/server/src/srv.cppm index d9ff880..5763bc5 100644 --- a/server/src/srv.cppm +++ b/server/src/srv.cppm @@ -63,17 +63,17 @@ public: auto unwrap() -> gpx::file&& { return std::visit( - util::overloaded{ - [](std::exception_ptr ex) -> gpx::file&& - { - if (ex) - std::rethrow_exception(ex); - else - throw std::runtime_error{"no GPX file parse result available"}; - }, - [](gpx::file&& f) -> gpx::file&& { return std::move(f); }, + util::overloaded{ + [](std::exception_ptr ex) -> gpx::file&& + { + if (ex) + std::rethrow_exception(ex); + else + throw std::runtime_error{"no GPX file parse result available"}; }, - std::move(res_)); + [](gpx::file&& f) -> gpx::file&& { return std::move(f); }, + }, + std::move(res_)); } }; @@ -100,7 +100,7 @@ struct readable_gpx_body auto init(boost::optional /* n */, beast::error_code& ec) noexcept - -> void + -> void { try { @@ -114,9 +114,9 @@ struct readable_gpx_body } } - auto - put(beast::concepts::const_buffer_sequence auto b, - beast::error_code& ec) noexcept -> std::size_t + auto put( + beast::concepts::const_buffer_sequence auto b, + beast::error_code& ec) noexcept -> std::size_t { auto total = 0uz; try @@ -125,9 +125,7 @@ struct readable_gpx_body it != net::buffer_sequence_end(b); it++) { r_.put( - std::string_view{ - static_cast(it->data()), it->size() - }); + std::string_view{static_cast(it->data()), it->size()}); total += it->size(); } ec = {}; @@ -168,25 +166,25 @@ public: private: auto handle_process_gpx(l0_ctx ctx, http::readable_request r) - -> net::awaitable + -> net::awaitable { auto gpx_file = gpx::file{}; try { auto req = - co_await http::read_request(ctx, std::move(r)); + co_await http::read_request(ctx, std::move(r)); gpx_file = std::move(req->body().unwrap()); } catch (std::exception& ex) { // TODO: more detailed problem reporting auto tpl = problem::tpl{ - .status = bhttp::status::bad_request, - .title = translate("Failed to parse GPX file"), - .type_uri = "https://routemon.fautchen.eu/problems/gpx-parse-failed", + .status = bhttp::status::bad_request, + .title = translate("Failed to parse GPX file"), + .type_uri = "https://routemon.fautchen.eu/problems/gpx-parse-failed", }; co_return http::problem_rsp( - ctx, tpl.instantiate(), http::keep_alive{false}); + ctx, tpl.instantiate(), http::keep_alive{false}); } // TODO: catch handler exceptions and return 500 when raised? @@ -195,17 +193,17 @@ private: if (!mres) { auto tpl = problem::tpl{ - .status = bhttp::status::internal_server_error, - .title = translate("Internal server error"), - .type_uri = "https://routemon.fautchen.eu/problems/" - "internal-server-error", + .status = bhttp::status::internal_server_error, + .title = translate("Internal server error"), + .type_uri = "https://routemon.fautchen.eu/problems/" + "internal-server-error", }; co_return http::problem_rsp( - ctx, tpl.instantiate(), http::keep_alive{true}); + ctx, tpl.instantiate(), http::keep_alive{true}); } auto rsp = http::make_rsp( - bhttp::status::ok, http::keep_alive{true}); + bhttp::status::ok, http::keep_alive{true}); rsp.set(bhttp::field::content_type, "application/json"); rsp.body() = json::serialize(json::value_from(*mres)); rsp.prepare_payload(); @@ -213,14 +211,14 @@ private: } auto handle_sysinfo(l0_ctx ctx, http::readable_request r) - -> net::awaitable + -> net::awaitable { auto req = - co_await http::read_request(ctx, std::move(r)); + co_await http::read_request(ctx, std::move(r)); auto info = inner_.sysinfo(); auto rsp = http::make_rsp( - bhttp::status::ok, http::keep_alive{true}); + bhttp::status::ok, http::keep_alive{true}); rsp.set(bhttp::field::content_type, "application/json"); rsp.body() = json::serialize(json::value_from(info)); rsp.prepare_payload(); @@ -236,17 +234,17 @@ public: { return std::bind_front(member, this); }; return http::dtree>{}.named_subtrees({ - {"gpx", - http::dtree{ - { - .post = handler(&handler::handle_process_gpx), - } - }.no_subtrees()}, - {"sysinfo", http::dtree{ - { - .get = handler(&handler::handle_sysinfo), - } - }.no_subtrees()}, + {"gpx", + http::dtree{ + { + .post = handler(&handler::handle_process_gpx), + } + }.no_subtrees()}, + {"sysinfo", http::dtree{ + { + .get = handler(&handler::handle_sysinfo), + } + }.no_subtrees()}, }); } }; @@ -257,13 +255,13 @@ export class server http::server srv_; static auto make_global_middleware() - -> http::middleware_t + -> http::middleware_t { return http::middleware_compose< - http::base_ctx, http::trace_id_ctx, - http::trace_id_ctx>( - http::trace_id_middleware, - http::lax_cors_middleware>); + http::base_ctx, http::trace_id_ctx, + http::trace_id_ctx>( + http::trace_id_middleware, + http::lax_cors_middleware>); } public: diff --git a/server/src/time.cppm b/server/src/time.cppm index 907cec4..d77a30b 100644 --- a/server/src/time.cppm +++ b/server/src/time.cppm @@ -31,7 +31,7 @@ public: } [[nodiscard]] auto except(period other) const - -> std::pair, std::optional> + -> std::pair, std::optional> { auto const before_start = start_; auto const before_end = other.start(); @@ -84,7 +84,7 @@ class period_seq if (preds.size() < 2) throw std::logic_error{ - "period_seq::consolidate: amount of predicates should be >= 2" + "period_seq::consolidate: amount of predicates should be >= 2" }; if (preds.front().second != ge) throw std::logic_error{"period_seq::consolidate: first element of preds " diff --git a/server/src/trace.cppm b/server/src/trace.cppm index 35d32f3..3dbed12 100644 --- a/server/src/trace.cppm +++ b/server/src/trace.cppm @@ -21,9 +21,9 @@ public: { namespace chrono = std::chrono; auto const unix_time_ms_signed = static_cast( - chrono::duration_cast( - chrono::system_clock::now().time_since_epoch()) - .count()); + chrono::duration_cast( + chrono::system_clock::now().time_since_epoch()) + .count()); if (unix_time_ms_signed < 0) throw std::runtime_error{"system time before UNIX epoch"}; auto const unix_time_ms = static_cast(unix_time_ms_signed); @@ -36,8 +36,8 @@ public: { unsigned long e = ERR_get_error(); throw std::runtime_error{std::format( - "failed to generate UUID(v7): {} ({}, code {})", - ERR_reason_error_string(e), ERR_lib_error_string(e), e)}; + "failed to generate UUID(v7): {} ({}, code {})", + ERR_reason_error_string(e), ERR_lib_error_string(e), e)}; } auto version = std::uint64_t{0b0111}; @@ -67,8 +67,8 @@ public: auto low_low = (low_ & 0x0000'ffff'ffff'ffff) >> 0; std::format_to( - target.begin(), "{:0>8x}-{:0>4x}-{:0>4x}-{:0>4x}-{:0>12x}", high_high, - high_low_high, low_low_high, high_low, low_low); + target.begin(), "{:0>8x}-{:0>4x}-{:0>4x}-{:0>4x}-{:0>12x}", high_high, + high_low_high, low_low_high, high_low, low_low); target.back() = '\0'; } }; diff --git a/server/src/util.cppm b/server/src/util.cppm index bdccf10..2e20e8b 100644 --- a/server/src/util.cppm +++ b/server/src/util.cppm @@ -14,9 +14,9 @@ struct overloaded : Ts... }; export constexpr auto parse_double( - std::string_view s, - std::chars_format fmt = std::chars_format::general) noexcept - -> std::optional + std::string_view s, + std::chars_format fmt = std::chars_format::general) noexcept + -> std::optional { auto x = 0.0; auto [_, ec] = std::from_chars(s.data(), s.data() + s.size(), x, fmt); @@ -31,9 +31,9 @@ export constexpr auto parse_double( } export constexpr auto parse_float( - std::string_view s, - std::chars_format fmt = std::chars_format::general) noexcept - -> std::optional + std::string_view s, + std::chars_format fmt = std::chars_format::general) noexcept + -> std::optional { auto x = 0.0; auto [_, ec] = std::from_chars(s.data(), s.data() + s.size(), x, fmt); @@ -62,7 +62,7 @@ public: static auto nil() -> std::shared_ptr> { return nullptr; } static auto cons(T v, std::shared_ptr const> l) - -> std::shared_ptr> + -> std::shared_ptr> { return std::shared_ptr>{new aolist{v, l}}; } @@ -75,8 +75,8 @@ public: export constexpr auto size_from_int(int x) -> std::optional { static_assert( - sizeof(int) <= sizeof(std::size_t), - "cannot cast int to smaller size_t type"); + sizeof(int) <= sizeof(std::size_t), + "cannot cast int to smaller size_t type"); if (x < 0) return std::nullopt; return static_cast(x); @@ -155,8 +155,7 @@ public: { s_ = rhs.s_; length_.store( - rhs.length_.load(std::memory_order_acquire), - std::memory_order_release); + rhs.length_.load(std::memory_order_acquire), std::memory_order_release); } return *this; } @@ -203,7 +202,7 @@ public: }; constexpr auto operator""_zsv(char const* s, std::size_t length) noexcept - -> zstring_view + -> zstring_view { return zstring_view{s, length}; } @@ -214,7 +213,7 @@ auto operator==(zstring_view lhs, zstring_view rhs) -> bool } export constexpr auto split_on(std::string_view s, char c) - -> std::pair> + -> std::pair> { if (auto i = s.find(c); i != std::string_view::npos) return std::make_pair(s.substr(0, i), s.substr(i + 1)); diff --git a/server/src/xml.cpp b/server/src/xml.cpp index c1b4358..7cf4415 100644 --- a/server/src/xml.cpp +++ b/server/src/xml.cpp @@ -22,7 +22,7 @@ executor::executor() : p_{XML_ParserCreateNS("UTF-8", detail::qname_sep)} XML_SetProcessingInstructionHandler(p_, handle_processing_instructions); XML_SetExternalEntityRefHandler(p_, handle_external_entity_ref); XML_SetNamespaceDeclHandler( - p_, handle_start_namespace_decl, handle_end_namespace_decl); + p_, handle_start_namespace_decl, handle_end_namespace_decl); XML_SetXmlDeclHandler(p_, handle_xml_decl); } @@ -41,7 +41,7 @@ auto executor::read(std::string_view xml, bool is_final) -> void throw std::runtime_error{"refusing to restart parser that was thrown in"}; // TODO: narrow_cast if (auto s = - XML_Parse(p_, xml.data(), static_cast(xml.size()), is_final); + XML_Parse(p_, xml.data(), static_cast(xml.size()), is_final); s != XML_STATUS_OK) { auto errc = XML_GetErrorCode(p_); @@ -53,7 +53,7 @@ auto executor::read(std::string_view xml, bool is_final) -> void else { throw std::runtime_error{std::format( - "failed to parse XML: {}", XML_ErrorString(errc))}; + "failed to parse XML: {}", XML_ErrorString(errc))}; } } } diff --git a/server/src/xml.cppm b/server/src/xml.cppm index ff27c5c..0c319e6 100644 --- a/server/src/xml.cppm +++ b/server/src/xml.cppm @@ -66,7 +66,7 @@ public: }; inline explicit attribute_view_iterator( - std::string_view default_ns_uri, char const* const* attrs) + std::string_view default_ns_uri, char const* const* attrs) : default_ns_uri_{default_ns_uri}, attrs_{attrs} { } @@ -105,7 +105,7 @@ class attribute_view : std::ranges::view_base public: inline explicit attribute_view( - std::string_view default_ns_uri, char const** attrs) + std::string_view default_ns_uri, char const** attrs) : default_ns_uri_{default_ns_uri}, attrs_{const_cast(attrs)} { @@ -122,7 +122,7 @@ public: } inline auto lookup(qname_view want) - -> std::optional> + -> std::optional> { for (auto const& [name, v] : *this) { @@ -200,8 +200,8 @@ struct eof_event }; using event = std::variant< - start_element_event, end_element_event, character_data_event, - processing_instructions_event, xml_decl_event, eof_event>; + start_element_event, end_element_event, character_data_event, + processing_instructions_event, xml_decl_event, eof_event>; template concept event_type = requires(event ev) { std::get(ev); }; @@ -237,7 +237,7 @@ public: } [[nodiscard]] inline auto continuation() const - -> std::coroutine_handle + -> std::coroutine_handle { return continuation_; } @@ -285,11 +285,11 @@ class executor s != XML_STATUS_OK) { ex_ = std::make_exception_ptr( - std::runtime_error{"unexpected error when stopping XML parser"}); + std::runtime_error{"unexpected error when stopping XML parser"}); return; } ex_ = std::make_exception_ptr( - std::runtime_error{"parser did not consume entire XML document"}); + std::runtime_error{"parser did not consume entire XML document"}); return; } continuation_.resume(); @@ -302,74 +302,74 @@ class executor static auto handle_start_element(void* ctx, char const* name, char const** attrs) noexcept - -> void + -> void { auto qname = detail::split_name(name); static_cast(ctx)->try_handle_event( - start_element_event{ - .name = qname, - .attrs = attribute_view{qname.ns_uri, attrs}, - }); + start_element_event{ + .name = qname, + .attrs = attribute_view{qname.ns_uri, attrs}, + }); } static auto handle_end_element(void* ctx, char const* name) noexcept -> void { static_cast(ctx)->try_handle_event( - end_element_event{ - .name = detail::split_name(name), - }); + end_element_event{ + .name = detail::split_name(name), + }); } static auto handle_character_data(void* ctx, char const* s, int len) noexcept - -> void + -> void { static_cast(ctx)->try_handle_event( - character_data_event{ - .data = std::string_view{s, static_cast(len)}, - }); + character_data_event{ + .data = std::string_view{s, static_cast(len)}, + }); } static auto handle_processing_instructions( - void* ctx, char const* target, char const* data) noexcept -> void + void* ctx, char const* target, char const* data) noexcept -> void { static_cast(ctx)->try_handle_event( - processing_instructions_event{ - .target = util::lazy_zstring_view{target}, - .data = util::lazy_zstring_view{data}, - }); + processing_instructions_event{ + .target = util::lazy_zstring_view{target}, + .data = util::lazy_zstring_view{data}, + }); } static auto handle_external_entity_ref( - XML_Parser, char const* /* context */, char const* /* base */, - char const* /* system_id */, char const* /* public_id */) noexcept -> int + XML_Parser, char const* /* context */, char const* /* base */, + char const* /* system_id */, char const* /* public_id */) noexcept -> int { return XML_STATUS_ERROR; } static auto handle_start_namespace_decl( - void* ctx, char const* prefix, char const* uri) noexcept -> void + void* ctx, char const* prefix, char const* uri) noexcept -> void { if (prefix) { static_cast(ctx) - ->namespaces_[std::string_view{prefix}] - .emplace_back(uri); + ->namespaces_[std::string_view{prefix}] + .emplace_back(uri); } else { static_cast(ctx)->default_namespace_.push_back( - uri ? std::make_optional(uri) : std::nullopt); + uri ? std::make_optional(uri) : std::nullopt); } } static auto handle_end_namespace_decl(void* ctx, char const* prefix) noexcept - -> void + -> void { if (prefix) { static_cast(ctx) - ->namespaces_[std::string_view{prefix}] - .pop_back(); + ->namespaces_[std::string_view{prefix}] + .pop_back(); } else { @@ -378,16 +378,16 @@ class executor } static auto handle_xml_decl( - void* ctx, char const* version, char const* encoding, - int standalone) noexcept -> void + void* ctx, char const* version, char const* encoding, + int standalone) noexcept -> void { static_cast(ctx)->try_handle_event( - xml_decl_event{ - .version = util::lazy_zstring_view{version}, - .encoding = util::lazy_zstring_view{encoding}, - .standalone = standalone < 0 ? std::nullopt - : std::make_optional(standalone > 0), - }); + xml_decl_event{ + .version = util::lazy_zstring_view{version}, + .encoding = util::lazy_zstring_view{encoding}, + .standalone = + standalone < 0 ? std::nullopt : std::make_optional(standalone > 0), + }); } inline auto advance_flag() -> bool { return advance_; } @@ -431,7 +431,7 @@ public: inline auto event() const -> std::optional const& { return ev_; } inline auto resolve_namespace(std::string_view prefix) - -> std::optional + -> std::optional { if (auto it = namespaces_.find(prefix); it != namespaces_.end() && !it->second.empty()) @@ -442,8 +442,8 @@ public: [[nodiscard]] inline auto position() -> position { return { - .line = XML_GetCurrentLineNumber(p_), - .col = XML_GetCurrentColumnNumber(p_), + .line = XML_GetCurrentLineNumber(p_), + .col = XML_GetCurrentColumnNumber(p_), }; } @@ -573,7 +573,7 @@ public: return false; } auto await_suspend(std::coroutine_handle> h) - -> std::coroutine_handle<> + -> std::coroutine_handle<> { // Passed coroutine handle will be the same as // parser::handle_type::from_promise(*this) @@ -621,13 +621,13 @@ using parser_result_t = T::result_type; template concept parser_invocable = - std::invocable - && parser_of, unconstrained>; + std::invocable + && parser_of, unconstrained>; template requires parser_invocable using parser_invoke_result_t = - parser_result_t>; + parser_result_t>; template auto expect_event(executor_ref e) -> parser @@ -637,28 +637,28 @@ auto expect_event(executor_ref e) -> parser { auto pos = e->position(); throw std::runtime_error{std::format( - "at {}:{}: unexpected event type, have {}", pos.line, pos.col, - ev.index())}; + "at {}:{}: unexpected event type, have {}", pos.line, pos.col, + ev.index())}; } e->set_advance_flag(); co_return std::get(ev); } inline auto expect_start_element(executor_ref e, qname_view want) - -> parser + -> parser { auto ev = co_await expect_event(e); if (ev.name != want) { auto pos = e->position(); throw std::runtime_error{std::format( - "at {}:{}: unexpected element started", pos.line, pos.col)}; + "at {}:{}: unexpected element started", pos.line, pos.col)}; } co_return ev.attrs; } inline auto allow_start_element(executor_ref e, qname_view want) - -> parser> + -> parser> { auto ev = co_await current_event(e); if (auto const* pev = std::get_if(&ev)) @@ -707,9 +707,9 @@ inline auto ignore_whitespace(executor_ref e) -> parser } auto expect_element( - executor_ref e, qname_view want, - parser_invocable auto p) - -> parser> + executor_ref e, qname_view want, + parser_invocable auto p) + -> parser> { co_await ignore_whitespace(e); auto attrs = co_await expect_start_element(e, want); @@ -717,14 +717,14 @@ auto expect_element( co_await expect_end_element(e, want); co_await ignore_whitespace(e); co_return std::forward< - parser_invoke_result_t>(res); + parser_invoke_result_t>(res); } auto allow_element( - executor_ref e, qname_view want, - parser_invocable auto p) - -> parser>> + executor_ref e, qname_view want, + parser_invocable auto p) + -> parser>> { co_await ignore_whitespace(e); if (auto mattrs = co_await allow_start_element(e, want)) @@ -733,18 +733,18 @@ auto allow_element( co_await expect_end_element(e, want); co_await ignore_whitespace(e); co_return std::make_optional( - std::forward< - parser_invoke_result_t>( - res)); + std::forward< + parser_invoke_result_t>( + res)); } co_return std::nullopt; } auto allow_element( - executor_ref e, qname_view want, - parser_invocable auto p) -> parser + executor_ref e, qname_view want, + parser_invocable auto p) -> parser requires std::is_void_v< - parser_invoke_result_t> + parser_invoke_result_t> { co_await ignore_whitespace(e); if (auto mattrs = co_await allow_start_element(e, want)) @@ -759,7 +759,7 @@ auto allow_element( inline auto ignore_contents(executor_ref e, std::optional muntil = std::nullopt) - -> parser + -> parser { std::size_t depth = 0; while (true) @@ -791,7 +791,7 @@ ignore_contents(executor_ref e, std::optional muntil = std::nullopt) } } inline auto ignore_element_contents(executor_ref e, attribute_view) - -> parser + -> parser { co_await ignore_contents(e); } @@ -814,7 +814,7 @@ inline auto read_string(executor_ref e) -> parser } } inline auto read_string_contents(executor_ref e, attribute_view) - -> parser + -> parser { co_return co_await read_string(e); } @@ -823,7 +823,7 @@ template auto hohalo() { return []( - Args&&... args) -> std::invoke_result_t + Args&&... args) -> std::invoke_result_t { co_return co_await f(std::forward(args)...); }; } -- cgit v1.3