aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-08-23 17:40:25 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-08-23 17:40:25 +0200
commitb5b8de1b3005ff6c6e3659d32b851a85f6671d88 (patch)
tree6f2a54196a3b2c2d29dfaeaf7e6a8b9e43f33ba6
parentb3e3f3f50e49c6d21032e44565a93ed96d99801b (diff)
downloadn_core-b5b8de1b3005ff6c6e3659d32b851a85f6671d88.tar.gz
n_core-b5b8de1b3005ff6c6e3659d32b851a85f6671d88.zip
added some helper functions and a nice enum for annotation handling, as well as an more complex reply example (multi annotaion, link annotation
-rw-r--r--CMakeLists.txt3
-rw-r--r--README.md2
-rw-r--r--include/AnnotationTypes.hpp23
-rw-r--r--include/Enum2String.hpp15
-rw-r--r--src/Enum2String.cpp9
-rw-r--r--src/main.cpp132
6 files changed, 132 insertions, 52 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 53d1f7e..aeecbf3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,9 +14,12 @@ ENDIF ()
add_executable(${PROJECT_NAME}
# Headers
+ include/AnnotationTypes.hpp
+ include/Enum2String.hpp
# Sources
src/main.cpp
+ src/Enum2String.cpp
)
target_include_directories(${PROJECT_NAME}
diff --git a/README.md b/README.md
index b5fd3d5..f1c42b1 100644
--- a/README.md
+++ b/README.md
@@ -60,4 +60,4 @@ The text should be printed as strikethrough. No extra content.
The text should be printed as underline. No extra content.
##### `link`
-The text should be formatted as a link. Extra content: the uri to link. \ No newline at end of file
+The text should be formatted as a link. Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri. \ No newline at end of file
diff --git a/include/AnnotationTypes.hpp b/include/AnnotationTypes.hpp
new file mode 100644
index 0000000..d61de08
--- /dev/null
+++ b/include/AnnotationTypes.hpp
@@ -0,0 +1,23 @@
+#if ( !defined(ANNOTATIONTYPES_HPP) || defined(GENERATE_ENUM_STRINGS) )
+
+#if (!defined(GENERATE_ENUM_STRINGS))
+#define ANNOTATIONTYPES_HPP
+#endif
+
+#include "Enum2String.hpp"
+
+///////////////////////////////
+// The enum declaration
+///////////////////////////////
+namespace Reply {
+ BEGIN_ENUM(AnnotationType) {
+ DECL_ENUM_ELEMENT(none),
+ DECL_ENUM_ELEMENT(bold),
+ DECL_ENUM_ELEMENT(italics),
+ DECL_ENUM_ELEMENT(strikethrough),
+ DECL_ENUM_ELEMENT(underline),
+ DECL_ENUM_ELEMENT(link),
+ } END_ENUM(AnnotationType)
+}
+
+#endif // (!defined(ANNOTATIONTYPES_HPP) || defined(GENERATE_ENUM_STRINGS)) \ No newline at end of file
diff --git a/include/Enum2String.hpp b/include/Enum2String.hpp
new file mode 100644
index 0000000..4992e0d
--- /dev/null
+++ b/include/Enum2String.hpp
@@ -0,0 +1,15 @@
+#undef DECL_ENUM_ELEMENT
+#undef BEGIN_ENUM
+#undef END_ENUM
+
+#ifndef GENERATE_ENUM_STRINGS
+#define DECL_ENUM_ELEMENT( element ) element
+#define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
+#define END_ENUM( ENUM_NAME ) ENUM_NAME; \
+ std::string GetString##ENUM_NAME(enum tag##ENUM_NAME index);
+#else
+#define DECL_ENUM_ELEMENT( element ) #element
+ #define BEGIN_ENUM( ENUM_NAME ) std::string gs_##ENUM_NAME [] =
+ #define END_ENUM( ENUM_NAME ) ; std::string GetString##ENUM_NAME(\
+ tag##ENUM_NAME index){ return gs_##ENUM_NAME [index]; }
+#endif \ No newline at end of file
diff --git a/src/Enum2String.cpp b/src/Enum2String.cpp
new file mode 100644
index 0000000..e64b6ea
--- /dev/null
+++ b/src/Enum2String.cpp
@@ -0,0 +1,9 @@
+/// The strings associated with the enums are generated here
+/////////////////////////////////////////////////////////////////////
+#include <string>
+
+#include "AnnotationTypes.hpp"
+
+#define GENERATE_ENUM_STRINGS // Start string generation
+#include "AnnotationTypes.hpp"
+#undef GENERATE_ENUM_STRINGS // Stop string generation \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 627d3d0..c704f39 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,15 +4,17 @@
#include "crow.h"
+#include "AnnotationTypes.hpp"
+
#define NULL_STRING std::string("null")
#define EMPTY_STRING std::string("")
#define NO_SUCH_COMMAND std::string("no_such_command")
-typedef std::function<crow::json::wvalue(std::string const &arguments, std::string const &session,
- void *payload)> handler_func;
+typedef crow::json::wvalue json;
+typedef std::function<json(std::string const &arguments, std::string const &session, void *payload)> handler_func;
struct CommandHandler {
- [[nodiscard]] crow::json::wvalue exec(std::string const &arguments, std::string const &session) const {
+ [[nodiscard]] json exec(std::string const &arguments, std::string const &session) const {
return func(arguments, session, payload);
}
@@ -20,18 +22,36 @@ struct CommandHandler {
void *payload{nullptr};
};
-crow::json::wvalue stopHandler(std::string const &arguments, std::string const &session, void *payload);
-crow::json::wvalue klingerHandler(std::string const &arguments, std::string const &session, void *payload);
+/* ------------------------------------------------------------------------------------------------------------------ */
+
+json stopHandler(std::string const &arguments, std::string const &session, void *payload);
+
+json wikiHandler(std::string const &arguments, std::string const &session, void *payload);
+
+json klingerHandler(std::string const &arguments, std::string const &session, void *payload);
+
+/* ------------------------------------------------------------------------------------------------------------------ */
+
+json simple_response(std::string const &text, std::string const &session = NULL_STRING, bool success = true);
-[[maybe_unused]] void decl_me_daddy(int not_an_int) { (void) not_an_int; }
+json create_annotation(Reply::AnnotationType annotation = Reply::AnnotationType::none,
+ std::string const &extra = EMPTY_STRING);
+
+json create_text(std::string const &text);
+json create_text(std::string const &text, std::vector<json> &&annotations);
+
+json create_response(std::vector<json> &&reply, std::string const &session = NULL_STRING, bool success = true);
+
+/* ------------------------------------------------------------------------------------------------------------------ */
int main() {
crow::SimpleApp app;
// command --> handler
static std::unordered_map<std::string, CommandHandler> const commands{
- {"stop", {stopHandler, &app}},
- {"klinger", {klingerHandler}}
+ {"stop", {stopHandler, &app}},
+ {"wiki", {wikiHandler}},
+ {"klinger", {klingerHandler}},
};
CROW_ROUTE(app, "/")
@@ -54,9 +74,7 @@ int main() {
return crow::response{handler.exec(arguments, session)};
}
- crow::json::wvalue response;
-
- return crow::response{"no such command!\n"};
+ return crow::response{simple_response("No such command!", NULL_STRING, false)};
});
app.port(18080).multithreaded().run();
@@ -64,63 +82,75 @@ int main() {
std::cout << "Stopped successfully" << std::endl;
}
-crow::json::wvalue klingerHandler(std::string const &arguments, std::string const &session, void *payload) {
- (void)payload;
-
- using namespace crow::json;
-
- crow::json::wvalue response(type::Object);
+/* ------------------------------------------------------------------------------------------------------------------ */
- std::vector<wvalue> reply_vec;
-
- std::vector<wvalue> annotation_vec;
-
- wvalue annotation(type::Object);
- annotation["type"] = "none";
- annotation["extra"] = "";
-
- annotation_vec.push_back(std::move(annotation));
+json klingerHandler(std::string const &arguments, std::string const &session, void *payload) {
+ (void) payload;
+ return simple_response("Bonjour!");
+}
- wvalue reply(type::Object);
- reply["text"] = "Bonjour!";
- reply["annotations"] = std::move(annotation_vec);
+json wikiHandler(std::string const &arguments, std::string const &session, void *payload) {
+ (void) payload;
- reply_vec.push_back(std::move(reply));
+ std::vector<json> linkAnnotations;
+ linkAnnotations.push_back(std::move(create_annotation(Reply::AnnotationType::link, "Wikipedia")));
+ linkAnnotations.push_back(std::move(create_annotation(Reply::AnnotationType::underline)));
- response["success"] = true;
- response["session"] = NULL_STRING;
- response["reply"] = std::move(reply_vec);
+ std::vector<json> reply_vec;
+ reply_vec.push_back(std::move(create_text("Visit ")));
+ reply_vec.push_back(std::move(create_text("https://eo.wikipedia.org/", std::move(linkAnnotations))));
+ reply_vec.push_back(std::move(create_text(" today!")));
- return response;
+ return create_response(std::move(reply_vec), session, true);
}
-crow::json::wvalue stopHandler(std::string const &arguments, std::string const &session, void *payload) {
- auto app = (crow::SimpleApp*) payload;
+json stopHandler(std::string const &arguments, std::string const &session, void *payload) {
+ auto app = (crow::SimpleApp *) payload;
app->stop();
- using namespace crow::json;
- crow::json::wvalue response(type::Object);
+ std::vector<json> annotations;
+ annotations.push_back(std::move(create_annotation(Reply::AnnotationType::bold)));
- std::vector<wvalue> reply_vec;
+ std::vector<json> reply_vec;
+ reply_vec.push_back(std::move(create_text("stopped", std::move(annotations))));
- std::vector<wvalue> annotation_vec;
+ return create_response(std::move(reply_vec), session, true);
+}
- wvalue annotation(type::Object);
- annotation["type"] = "bold";
- annotation["extra"] = "";
+/* ------------------------------------------------------------------------------------------------------------------ */
- annotation_vec.push_back(std::move(annotation));
+json simple_response(std::string const &text, std::string const &session, bool success) {
+ std::vector<json> reply_vec;
+ reply_vec.push_back(std::move(create_text(text)));
- wvalue reply(type::Object);
- reply["text"] = "stopped.";
- reply["annotations"] = std::move(annotation_vec);
+ return create_response(std::move(reply_vec), session, success);
+}
- reply_vec.push_back(std::move(reply));
+json create_annotation(Reply::AnnotationType annotationType, std::string const &extra) {
+ json annotation(crow::json::type::Object);
+ annotation["type"] = Reply::GetStringAnnotationType(annotationType);
+ annotation["extra"] = extra;
+ return annotation;
+}
- response["success"] = true;
- response["session"] = NULL_STRING;
- response["reply"] = std::move(reply_vec);
+json create_text(std::string const &text) {
+ std::vector<json> annotations;
+ annotations.push_back(std::move(create_annotation()));
+ return create_text(text, std::move(annotations));
+}
+
+json create_text(std::string const &text, std::vector<json> &&annotations) {
+ json reply(crow::json::type::Object);
+ reply["text"] = text;
+ reply["annotations"] = std::move(annotations);
+ return reply;
+}
+json create_response(std::vector<json> &&reply, std::string const &session, bool success) {
+ json response(crow::json::type::Object);
+ response["success"] = success;
+ response["session"] = session;
+ response["reply"] = std::move(reply);
return response;
}