mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Added basic blueprint support (registration and prefix)
This commit is contained in:
parent
a8e55b7a09
commit
c46af69f41
@ -73,6 +73,10 @@ else ()
|
||||
target_compile_options(example_json_map PRIVATE "${compiler_options}")
|
||||
target_link_libraries(example_json_map PUBLIC ${REQUIRED_LIBRARIES})
|
||||
|
||||
add_executable(example_blueprint example_blueprint.cpp)
|
||||
target_compile_options(example_blueprint PRIVATE "${compiler_options}")
|
||||
target_link_libraries(example_blueprint PUBLIC ${REQUIRED_LIBRARIES})
|
||||
|
||||
add_custom_command(OUTPUT example_chat.html
|
||||
COMMAND ${CMAKE_COMMAND} -E
|
||||
copy ${PROJECT_SOURCE_DIR}/example_chat.html ${CMAKE_CURRENT_BINARY_DIR}/example_chat.html
|
||||
|
18
examples/example_blueprint.cpp
Normal file
18
examples/example_blueprint.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#define CROW_MAIN
|
||||
#include "crow.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
crow::SimpleApp app;
|
||||
|
||||
crow::Blueprint bp("bp_prefix");
|
||||
|
||||
CROW_BP_ROUTE(app, bp, "/")
|
||||
([]() {
|
||||
return "Hello world!";
|
||||
});
|
||||
|
||||
app.register_blueprint(bp);
|
||||
|
||||
app.port(18080).run();
|
||||
}
|
@ -24,8 +24,10 @@
|
||||
|
||||
#ifdef CROW_MSVC_WORKAROUND
|
||||
#define CROW_ROUTE(app, url) app.route_dynamic(url)
|
||||
#define CROW_BP_ROUTE(app, blueprint, url) app.route_dynamic(blueprint, url)
|
||||
#else
|
||||
#define CROW_ROUTE(app, url) app.route<crow::black_magic::get_parameter_tag(url)>(url)
|
||||
#define CROW_BP_ROUTE(app, blueprint, url) app.route<crow::black_magic::get_parameter_tag(url)>(blueprint, url)
|
||||
#endif
|
||||
#define CROW_CATCHALL_ROUTE(app) app.catchall_route()
|
||||
|
||||
@ -80,14 +82,28 @@ namespace crow
|
||||
return router_.new_rule_dynamic(std::move(rule));
|
||||
}
|
||||
|
||||
///Create a dynamic route for a blueprint using a rule (**Use CROW_ROUTE instead**)
|
||||
DynamicRule& route_dynamic(Blueprint& blueprint, std::string&& rule)
|
||||
{
|
||||
return blueprint.new_rule_dynamic(std::move(rule));
|
||||
}
|
||||
|
||||
///Create a route using a rule (**Use CROW_ROUTE instead**)
|
||||
template <uint64_t Tag>
|
||||
auto route(std::string&& rule)
|
||||
-> typename std::result_of<decltype(&Router::new_rule_tagged<Tag>)(Router, std::string&&)>::type
|
||||
{
|
||||
{//TODO process the blueprint
|
||||
return router_.new_rule_tagged<Tag>(std::move(rule));
|
||||
}
|
||||
|
||||
///Create a route for a blueprint using a rule (**Use CROW_ROUTE instead**)
|
||||
template <uint64_t Tag>
|
||||
auto route(Blueprint& blueprint, std::string&& rule)
|
||||
-> typename std::result_of<decltype(&Router::new_rule_tagged<Tag>)(Router, std::string&&)>::type
|
||||
{
|
||||
return blueprint.new_rule_tagged<Tag>(std::move(rule));
|
||||
}
|
||||
|
||||
///Create a route for any requests without a proper route (**Use CROW_CATCHALL_ROUTE instead**)
|
||||
CatchallRule& catchall_route()
|
||||
{
|
||||
@ -158,12 +174,21 @@ namespace crow
|
||||
/// crow::LogLevel::Warning (2)<br>
|
||||
/// crow::LogLevel::Error (3)<br>
|
||||
/// crow::LogLevel::Critical (4)<br>
|
||||
self_t& loglevel(crow::LogLevel level)
|
||||
self_t& loglevel(LogLevel level)
|
||||
{
|
||||
crow::logger::setLogLevel(level);
|
||||
return *this;
|
||||
}
|
||||
|
||||
self_t& register_blueprint(Blueprint& blueprint)
|
||||
{
|
||||
if (blueprints_.empty() || std::find(blueprints_.begin(), blueprints_.end(), &blueprint) == blueprints_.end())
|
||||
{
|
||||
blueprints_.emplace_back(&blueprint);
|
||||
}//TODO error throwing
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Set a custom duration and function to run on every tick
|
||||
template <typename Duration, typename Func>
|
||||
self_t& tick(Duration d, Func f) {
|
||||
@ -191,7 +216,7 @@ namespace crow
|
||||
///Go through the rules, upgrade them if possible, and add them to the list of rules
|
||||
void validate()
|
||||
{
|
||||
router_.validate();
|
||||
router_.validate(blueprints_);
|
||||
}
|
||||
|
||||
///Notify anything using `wait_for_server_start()` to proceed
|
||||
@ -380,6 +405,8 @@ namespace crow
|
||||
|
||||
std::vector<int> signals_{SIGINT, SIGTERM};
|
||||
|
||||
std::vector<Blueprint*> blueprints_;
|
||||
|
||||
bool server_started_{false};
|
||||
std::condition_variable cv_started_;
|
||||
std::mutex start_mutex_;
|
||||
|
@ -1029,6 +1029,94 @@ namespace crow
|
||||
std::vector<Node> nodes_;
|
||||
};
|
||||
|
||||
/// A blueprint can be considered a smaller section of a Crow app, specifically where the router is conecerned.
|
||||
class Blueprint
|
||||
{
|
||||
public:
|
||||
Blueprint()
|
||||
{
|
||||
}
|
||||
|
||||
Blueprint(const std::string& prefix):
|
||||
prefix_(prefix){};
|
||||
|
||||
Blueprint(std::string&& prefix):
|
||||
prefix_(prefix){};
|
||||
/*
|
||||
Blueprint(Blueprint& other)
|
||||
{
|
||||
prefix_ = std::move(other.prefix_);
|
||||
all_rules_ = std::move(other.all_rules_);
|
||||
}
|
||||
|
||||
Blueprint(const Blueprint& other)
|
||||
{
|
||||
prefix_ = other.prefix_;
|
||||
all_rules_ = other.all_rules_;
|
||||
}
|
||||
*/
|
||||
Blueprint(Blueprint&& value)
|
||||
{
|
||||
*this = std::move(value);
|
||||
}
|
||||
|
||||
Blueprint& operator = (const Blueprint& value) = delete;
|
||||
|
||||
Blueprint& operator = (Blueprint&& value) noexcept
|
||||
{
|
||||
prefix_ = std::move(value.prefix_);
|
||||
all_rules_ = std::move(value.all_rules_);
|
||||
catchall_rule_ = std::move(value.catchall_rule_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (const Blueprint& value)
|
||||
{
|
||||
return value.prefix() == prefix_;
|
||||
}
|
||||
|
||||
bool operator != (const Blueprint& value)
|
||||
{
|
||||
return value.prefix() != prefix_;
|
||||
}
|
||||
|
||||
std::string prefix() const
|
||||
{
|
||||
return prefix_;
|
||||
}
|
||||
|
||||
DynamicRule& new_rule_dynamic(const std::string& rule)
|
||||
{
|
||||
std::string new_rule = '/' + prefix_ + rule;
|
||||
auto ruleObject = new DynamicRule(new_rule);
|
||||
all_rules_.emplace_back(ruleObject);
|
||||
|
||||
return *ruleObject;
|
||||
}
|
||||
|
||||
template <uint64_t N>
|
||||
typename black_magic::arguments<N>::type::template rebind<TaggedRule>& new_rule_tagged(const std::string& rule)
|
||||
{
|
||||
std::string new_rule = '/' + prefix_ + rule;
|
||||
using RuleT = typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
|
||||
|
||||
auto ruleObject = new RuleT(new_rule);
|
||||
all_rules_.emplace_back(ruleObject);
|
||||
|
||||
return *ruleObject;
|
||||
}
|
||||
|
||||
CatchallRule& catchall_rule()
|
||||
{
|
||||
return catchall_rule_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string prefix_;
|
||||
std::vector<std::unique_ptr<BaseRule>> all_rules_;
|
||||
CatchallRule catchall_rule_;
|
||||
friend class Router;
|
||||
};
|
||||
|
||||
/// Handles matching requests to existing rules and upgrade requests.
|
||||
class Router
|
||||
@ -1088,8 +1176,20 @@ namespace crow
|
||||
|
||||
}
|
||||
|
||||
void validate()
|
||||
void validate(std::vector<Blueprint*>& bp_list)
|
||||
{
|
||||
//Take all the routes from the registered blueprints and add them to `all_rules_` to be processed.
|
||||
if (!(bp_list.empty()))
|
||||
{
|
||||
for (Blueprint* bp : bp_list)
|
||||
{
|
||||
for (auto& rule: bp->all_rules_)
|
||||
{
|
||||
all_rules_.push_back(std::move(rule));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& rule:all_rules_)
|
||||
{
|
||||
if (rule)
|
||||
|
Loading…
Reference in New Issue
Block a user