#include #include #include #include #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; using ErrorsList = std::vector; /* define << for ResultT and Node (below) to print results */ static std::ostream& operator <<(std::ostream& os, const ResultT& val) { if (const std::string* pval = std::get_if(&val)) std::cout << "'" << *pval << "'"; else if (const StatusT* code = std::get_if(&val)) std::cout << "Error " << *code << ": " << httplib::status_message(*code); return os; } /* tree */ template struct Node { T value; std::vector> children; Node() = delete; Node(const T& val) : value(val) {} void insert(Node& node) { if (node.value == value) return; children.push_back(node); } friend std::ostream& operator <<(std::ostream& os, const Node& val) { os << "[" << val.value << "]"; if (!val.children.empty()) os << "\nChildren:\t"; std::for_each(val.children.cbegin(), val.children.cend(), [&os] (const Node node) { os << node; }); return os; } }; using CommentTree = Node; template Node traverse(const Node& src, T3 f) { Node result(f(src.value)); std::for_each(src.children.cbegin(), src.children.cend(), [&] (const Node& node) { result.children.push_back(traverse(node, f)); }); return result; } template void forAll(const Node &src, std::vector &result, T3 f) { f(src.value, result); std::for_each(src.children.cbegin(), src.children.cend(), [&] (const Node& node) { forAll(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(res->status); } static std::variant tryGetContent(const Node &src, ErrorsList &errors) { httplib::Client cli(cSite); auto actionGet = [&] (const int x) { return tryGetContent(cli, x); }; CommentTree result = traverse(src, actionGet); auto collectErrors = [&] (const CommentTree& node, ErrorsList& list) { if (const StatusT* code = std::get_if(&node.value)) list.push_back(*code); }; forAll(result, errors, collectErrors); if (errors.size() > 0) return errors; return result; } int main() { using IntNode = Node; 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; ErrorsList errors; auto result = tryGetContent(root, errors); /* print result */ if (const auto *list = std::get_if(&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(&result)) { std::cout << "\n Result:\n"; std::cout << *node; } return 0; }