Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <variant>
- #include <string>
- #include <iostream>
- #include "cpp-httplib/httplib.h"
- const std::string cSite { "http://kit.local" };
- const std::string cUrlComment { "/comment/?id=" };
- using StatusT = httplib::StatusCode;
- using ResultT = std::variant<std::string, StatusT>;
- using ErrorsList = std::vector<StatusT>;
- /* define << for ResultT and Node<T> (below) to print results */
- static std::ostream& operator <<(std::ostream& os, const ResultT& val) {
- if (const std::string* pval = std::get_if<std::string>(&val))
- std::cout << "'" << *pval << "'";
- else if (const StatusT* code = std::get_if<StatusT>(&val))
- std::cout << "Error " << *code << ": " << httplib::status_message(*code);
- return os;
- }
- /* tree */
- template<typename T>
- struct Node {
- T value;
- std::vector<Node<T>> children;
- Node() = delete;
- Node(const T& val) : value(val) {}
- void insert(const Node<T>& node)
- {
- if (node.value == value)
- return;
- children.push_back(node);
- }
- friend std::ostream& operator <<(std::ostream& os, const Node<T>& val)
- {
- os << "[" << val.value << "]";
- if (!val.children.empty())
- os << "\nChildren:\t";
- std::for_each(val.children.cbegin(), val.children.cend(),
- [&os] (const Node<T> node) { os << node; });
- return os;
- }
- };
- using CommentTree = Node<ResultT>;
- template<typename T1, typename T2, typename T3>
- Node<T2> traverse(const Node<T1>& src, T3 f) {
- Node<T2> result(f(src.value));
- std::for_each(src.children.cbegin(), src.children.cend(),
- [&] (const Node<T1>& node) {
- result.children.push_back(traverse<T1, T2, T3>(node, f));
- });
- return result;
- }
- template<typename T1, typename T2, typename T3>
- void forAll(const Node<T1>& src, std::vector<T2>& result, T3 f) {
- f(src.value, result);
- std::for_each(src.children.cbegin(), src.children.cend(),
- [&] (const Node<T1>& node) {
- forAll<T1, T2, T3>(node, result, f);
- });
- }
- static ResultT tryGetContent(httplib::Client& c, const int x) {
- auto res = c.Get(cUrlComment + std::to_string(x));
- if (res->status == StatusT::OK_200)
- return res->body;
- return static_cast<StatusT>(res->status);
- }
- static std::variant<CommentTree, ErrorsList>
- tryGetContent(const Node<int>& src) {
- httplib::Client cli(cSite);
- auto actionGet = [&] (const int x) {
- return tryGetContent(cli, x);
- };
- CommentTree result = traverse<int, ResultT, decltype(actionGet)>(src, actionGet);
- ErrorsList errors;
- auto collectErrors = [&] (const CommentTree& node, ErrorsList& list) {
- if (const StatusT* code = std::get_if<StatusT>(&node.value))
- list.push_back(*code);
- };
- forAll<ResultT, StatusT, decltype(collectErrors)>(result, errors, collectErrors);
- if (!errors.empty())
- return errors;
- return result;
- }
- int main() {
- using IntNode = Node<int>;
- IntNode tree { 10 };
- IntNode a { 100 }, b { 101 }, c { 102 };
- IntNode bb { 1001 };
- b.insert(bb);
- tree.insert(a);
- tree.insert(b);
- tree.insert(c);
- IntNode root { 1 };
- root.insert(tree);
- std::cout << "\n Source:\n";
- std::cout << root;
- auto result = tryGetContent(root);
- /* print result */
- if (const auto* list = std::get_if<ErrorsList>(&result)) {
- std::for_each(list->cbegin(), list->cend(), [&](const StatusT code) {
- std::cout << "\nError " << code << ": " << httplib::status_message(code);
- });
- } else if (const auto* node = std::get_if<CommentTree>(&result)) {
- std::cout << "\n Result:\n";
- std::cout << *node;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment