Advertisement
Galebickosikasa

Untitled

May 23rd, 2021
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.31 KB | None | 0 0
  1. #include "test_runner.h"
  2. #include <functional>
  3. #include <memory>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include <string>
  7. #include <vector>
  8.  
  9. using namespace std;
  10.  
  11.  
  12. struct Email {
  13. string from;
  14. string to;
  15. string body;
  16. };
  17.  
  18.  
  19. class Worker {
  20. public:
  21. virtual ~Worker() = default;
  22. virtual void Process(unique_ptr<Email> email) = 0;
  23. virtual void Run() {
  24. throw logic_error("Unimplemented");
  25. }
  26.  
  27. protected:
  28. void PassOn(unique_ptr<Email> email) const {
  29. if (next) next->Process (move (email));
  30. }
  31.  
  32. public:
  33. void SetNext(unique_ptr<Worker> next_) {
  34. next = move (next_);
  35. }
  36. private:
  37. unique_ptr<Worker> next;
  38. };
  39.  
  40.  
  41. class Reader : public Worker {
  42. public:
  43. explicit Reader (istream& in_) : in (in_) {}
  44.  
  45. void Run () override {
  46. while (true) {
  47. unique_ptr<Email> email = make_unique<Email>();
  48. getline (in, email->from);
  49. getline (in, email->to);
  50. getline (in, email->body);
  51. if (!in) break;
  52. PassOn (move (email));
  53. }
  54. }
  55.  
  56. void Process (unique_ptr <Email> email) override {}
  57. private:
  58. istream& in;
  59. };
  60.  
  61.  
  62. class Filter : public Worker {
  63. public:
  64. using Function = function<bool(const Email&)>;
  65.  
  66. public:
  67. explicit Filter (Function f_) : f (move (f_)) {}
  68.  
  69. void Process (unique_ptr<Email> email) override {
  70. if (f (*email)) {
  71. PassOn (move (email));
  72. }
  73. }
  74.  
  75. private:
  76. Function f;
  77. };
  78.  
  79.  
  80. class Copier : public Worker {
  81. public:
  82. explicit Copier (string to_) : to (move (to_)) {}
  83.  
  84. void Process (unique_ptr <Email> email) override {
  85. unique_ptr <Email> email_copy;
  86. if (email->to != to) {
  87. email_copy = make_unique<Email>(*email);
  88. email_copy->to = to;
  89. }
  90. PassOn (move (email));
  91. if (email_copy) PassOn (move (email_copy));
  92. }
  93.  
  94. private:
  95. string to;
  96. };
  97.  
  98.  
  99. class Sender : public Worker {
  100. public:
  101. explicit Sender (ostream& out_) : out (out_) {}
  102.  
  103. void Process (unique_ptr <Email> email) override {
  104. out << email->from << '\n' << email->to << '\n' << email->body << '\n';
  105. PassOn (move (email));
  106. }
  107. private:
  108. ostream& out;
  109. };
  110.  
  111.  
  112. class PipelineBuilder {
  113. public:
  114. explicit PipelineBuilder(istream& in) {
  115. v.emplace_back (make_unique<Reader>(in));
  116. }
  117.  
  118. PipelineBuilder& FilterBy(Filter::Function filter_) {
  119. v.emplace_back (make_unique<Filter>(move (filter_)));
  120. return *this;
  121. }
  122.  
  123. PipelineBuilder& CopyTo(string recipient) {
  124. v.emplace_back (make_unique<Copier>(move (recipient)));
  125. return *this;
  126. }
  127.  
  128. PipelineBuilder& Send(ostream& out) {
  129. v.emplace_back (make_unique<Sender> (out));
  130. return *this;
  131. }
  132.  
  133. unique_ptr<Worker> Build() {
  134. for (int i = (int)v.size () - 2; i >= 0; --i) v[i]->SetNext (move (v[i + 1]));
  135. return move (v.front ());
  136. }
  137.  
  138. private:
  139. vector<unique_ptr<Worker>> v;
  140. };
  141.  
  142.  
  143. void TestSanity() {
  144. string input = (
  145. "erich@example.com\n"
  146. "richard@example.com\n"
  147. "Hello there\n"
  148.  
  149. "erich@example.com\n"
  150. "ralph@example.com\n"
  151. "Are you sure you pressed the right button?\n"
  152.  
  153. "ralph@example.com\n"
  154. "erich@example.com\n"
  155. "I do not make mistakes of that kind\n"
  156. );
  157. istringstream inStream(input);
  158. ostringstream outStream;
  159.  
  160. PipelineBuilder builder(inStream);
  161. builder.FilterBy([](const Email& email) {
  162. return email.from == "erich@example.com";
  163. });
  164. builder.CopyTo("richard@example.com");
  165. builder.Send(outStream);
  166. auto pipeline = builder.Build();
  167.  
  168. pipeline->Run();
  169.  
  170. string expectedOutput = (
  171. "erich@example.com\n"
  172. "richard@example.com\n"
  173. "Hello there\n"
  174.  
  175. "erich@example.com\n"
  176. "ralph@example.com\n"
  177. "Are you sure you pressed the right button?\n"
  178.  
  179. "erich@example.com\n"
  180. "richard@example.com\n"
  181. "Are you sure you pressed the right button?\n"
  182. );
  183.  
  184. ASSERT_EQUAL(expectedOutput, outStream.str());
  185. }
  186.  
  187. //int main() {
  188. // TestRunner tr;
  189. // RUN_TEST(tr, TestSanity);
  190. // return 0;
  191. //}
  192.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement