Skip to content

Commit bc09ea4

Browse files
committed
Small cleanups in routes.cpp
1 parent cb3c827 commit bc09ea4

File tree

3 files changed

+47
-84
lines changed

3 files changed

+47
-84
lines changed

include/cgimap/router.hpp

-10
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,6 @@ struct match_osm_id : public ops<match_osm_id> {
138138
match_type match(part_iterator &begin, const part_iterator &end) const;
139139
};
140140

141-
/**
142-
* match any string.
143-
*/
144-
struct match_name : public ops<match_name> {
145-
using match_type = list<std::string>;
146-
match_name() = default;
147-
match_type match(part_iterator &begin, const part_iterator &end) const;
148-
};
149-
150141
/**
151142
* null match - it'll match anything. it's only here to anchor the expression
152143
* with the correct type, allowing us to write the rest of the expression
@@ -161,7 +152,6 @@ struct match_begin : public ops<match_begin> {
161152
// match items, given nicer names so that expressions are easier to read.
162153
static const match_begin root_;
163154
static const match_osm_id osm_id_;
164-
static const match_name name_;
165155
}
166156

167157
#endif /* ROUTER_HPP */

src/router.cpp

+3-17
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ match_string::match_type match_string::match(part_iterator &begin,
2121
const part_iterator &end) const {
2222
bool matches = false;
2323
if (begin != end) {
24-
std::string bit = *begin;
25-
matches = bit == str;
24+
const std::string& bit = *begin;
25+
matches = (bit == str);
2626
++begin;
2727
}
2828
if (!matches) {
@@ -35,7 +35,7 @@ match_osm_id::match_type match_osm_id::match(part_iterator &begin,
3535
const part_iterator &end) const {
3636
if (begin != end) {
3737
try {
38-
std::string bit = *begin;
38+
const std::string& bit = *begin;
3939
// note that osm_nwr_id_t is actually unsigned, so we lose a bit of
4040
// precision here, but it's OK since IDs are postgres 'bigint' types
4141
// which are also signed, so element 2^63 is unlikely to exist.
@@ -51,25 +51,11 @@ match_osm_id::match_type match_osm_id::match(part_iterator &begin,
5151
throw error();
5252
}
5353

54-
match_name::match_type match_name::match(part_iterator &begin,
55-
const part_iterator &end) const {
56-
if (begin != end) {
57-
try {
58-
std::string bit = *begin++;
59-
return match_type(bit);
60-
} catch (std::exception &e) {
61-
throw error();
62-
}
63-
}
64-
throw error();
65-
}
66-
6754
match_begin::match_type match_begin::match(part_iterator &,
6855
const part_iterator &) const {
6956
return match_type();
7057
}
7158

7259
extern const match_begin root_; // @suppress("Unused variable declaration in file scope")
7360
extern const match_osm_id osm_id_; // @suppress("Unused variable declaration in file scope")
74-
extern const match_name name_; // @suppress("Unused variable declaration in file scope")
7561
}

src/routes.cpp

+44-57
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@
6060
#include <boost/algorithm/string.hpp>
6161
#include <fmt/core.h>
6262

63-
using boost::fusion::make_cons;
64-
using boost::fusion::invoke;
65-
66-
namespace al = boost::algorithm;
6763

6864
/**
6965
* maps router DSL expressions to constructors for handlers. this means it's
@@ -77,21 +73,11 @@ struct router {
7773
virtual bool invoke_if(const std::vector<std::string> &, request &, handler_ptr_t &) = 0;
7874
};
7975

80-
using rule_ptr = std::unique_ptr<rule_base>;
81-
8276
// concrete rule match / constructor class
83-
template <typename rule_t, typename func_t>
77+
template <typename Handler, typename Rule>
8478
struct rule : public rule_base {
85-
// the DSL rule expression to match
86-
rule_t r;
87-
88-
// the function to call (used later as constructor factory)
89-
func_t func;
90-
91-
rule(rule_t r_, func_t f_) :
92-
r(std::move(r_)),
93-
func(f_)
94-
{}
79+
explicit rule(Rule&& r) : r(std::move(r)) {}
80+
~rule() override = default;
9581

9682
// try to match the expression. if it succeeds, call the provided function
9783
// with the provided params and the matched DSL arguments.
@@ -101,15 +87,24 @@ struct router {
10187
try {
10288
auto begin = parts.begin();
10389
auto sequence = r.match(begin, parts.end());
104-
if(begin!=parts.end())
105-
throw match::error();
90+
91+
if (begin != parts.end())
92+
return false; // no match
93+
94+
// the function to call (used later as constructor factory)
95+
boost::factory<Handler *> func{};
96+
10697
ptr.reset(
107-
invoke(func, make_cons(std::ref(params), sequence)));
108-
return true;
98+
boost::fusion::invoke(func, boost::fusion::make_cons(std::ref(params), sequence)));
10999
} catch (const match::error &e) {
110100
return false;
111101
}
102+
return true;
112103
}
104+
105+
private:
106+
// the DSL rule expression to match
107+
Rule r;
113108
};
114109

115110
/* add a match all methods rule (a DSL expression) which constructs the Handler
@@ -119,47 +114,36 @@ struct router {
119114
*/
120115

121116
// add rule to match HTTP GET method only
122-
template <typename Handler, typename Rule> router& GET(Rule r) {
123-
// functor to create Handler instances
124-
boost::factory<Handler *> ctor;
117+
template <typename Handler, typename Rule> router& GET(Rule&& r) {
125118

126119
static_assert(std::is_base_of<handler, Handler>::value, "GET rule requires handler subclass");
127120
static_assert(!std::is_base_of<payload_enabled_handler, Handler>::value, "GET rule cannot use payload enabled handler subclass");
128121

129-
rules_get.push_back(
130-
rule_ptr(new rule<Rule, boost::factory<Handler *> >(std::move(r), ctor)));
122+
rules_get.push_back(std::make_unique<rule<Handler, Rule> >(std::move(r)));
131123
return *this;
132124
}
133125

134126
// add rule to match HTTP POST method only
135-
template <typename Handler, typename Rule> router& POST(Rule r) {
136-
// functor to create Handler instances
137-
boost::factory<Handler *> ctor;
127+
template <typename Handler, typename Rule> router& POST(Rule&& r) {
138128

139129
static_assert(std::is_base_of<payload_enabled_handler, Handler>::value, "POST rule requires payload enabled handler subclass");
140130

141-
rules_post.push_back(
142-
rule_ptr(new rule<Rule, boost::factory<Handler *> >(std::move(r), ctor)));
131+
rules_post.push_back(std::make_unique<rule<Handler, Rule> >(std::move(r)));
143132
return *this;
144133
}
145134

146-
147135
// add rule to match HTTP PUT method only
148-
template <typename Handler, typename Rule> router& PUT(Rule r) {
149-
// functor to create Handler instances
150-
boost::factory<Handler *> ctor;
136+
template <typename Handler, typename Rule> router& PUT(Rule&& r) {
151137

152138
static_assert(std::is_base_of<payload_enabled_handler, Handler>::value, "PUT rule requires payload enabled handler subclass");
153139

154-
rules_put.push_back(
155-
rule_ptr(new rule<Rule, boost::factory<Handler *> >(std::move(r), ctor)));
140+
rules_put.push_back(std::make_unique<rule<Handler, Rule> >(std::move(r)));
156141
return *this;
157142
}
158143

159144
/* match the list of path components given in p. if a match is found,
160-
* construct an
161-
* object of the handler type with the provided params and the matched
162-
* params.
145+
* construct an object of the handler type with the provided params
146+
* and the matched params.
163147
*/
164148

165149
handler_ptr_t match(const std::vector<std::string> &p, request &params) {
@@ -221,6 +205,8 @@ struct router {
221205
}
222206

223207
private:
208+
using rule_ptr = std::unique_ptr<rule_base>;
209+
224210
std::vector<rule_ptr> rules_get;
225211
std::vector<rule_ptr> rules_post;
226212
std::vector<rule_ptr> rules_put;
@@ -291,43 +277,44 @@ namespace {
291277
std::pair<std::string, mime::type> resource_mime_type(const std::string &path) {
292278

293279
#if HAVE_YAJL
294-
{
295-
std::size_t json_found = path.rfind(".json");
296280

297-
if (json_found != std::string::npos && json_found == path.length() - 5) {
298-
return std::make_pair(path.substr(0, json_found), mime::type::application_json);
299-
}
300-
}
281+
std::size_t json_found = path.rfind(".json");
282+
283+
if (json_found != std::string::npos && json_found == path.length() - 5) {
284+
return {path.substr(0, json_found), mime::type::application_json};
285+
}
286+
301287
#endif
302288

303-
{
304-
std::size_t xml_found = path.rfind(".xml");
289+
std::size_t xml_found = path.rfind(".xml");
305290

306-
if (xml_found != std::string::npos && xml_found == path.length() - 4) {
307-
return make_pair(path.substr(0, xml_found), mime::type::application_xml);
308-
}
309-
}
291+
if (xml_found != std::string::npos && xml_found == path.length() - 4) {
292+
return {path.substr(0, xml_found), mime::type::application_xml};
293+
}
310294

311-
return make_pair(path, mime::type::unspecified_type);
295+
return make_pair(path, mime::type::unspecified_type);
312296
}
313297

314298
handler_ptr_t route_resource(request &req, const std::string &path,
315299
const std::unique_ptr<router> &r) {
300+
301+
namespace al = boost::algorithm;
302+
316303
// strip off the format-spec, if there is one
317-
std::pair<std::string, mime::type> resource = resource_mime_type(path);
304+
auto [resource, mime_type] = resource_mime_type(path);
318305

319306
// split the URL into bits to be matched.
320307
std::vector<std::string> path_components;
321-
al::split(path_components, resource.first, al::is_any_of("/"));
308+
al::split(path_components, resource, al::is_any_of("/"));
322309

323-
handler_ptr_t hptr(r->match(path_components, req));
310+
auto hptr(r->match(path_components, req));
324311

325312
// if the pointer points at something, then the path was found. otherwise,
326313
// it must have exhausted all the possible routes.
327314
if (hptr) {
328315
// ugly hack - need this info later on to choose the output formatter,
329316
// but don't want to parse the URI again...
330-
hptr->set_resource_type(resource.second);
317+
hptr->set_resource_type(mime_type);
331318
}
332319

333320
return hptr;

0 commit comments

Comments
 (0)