Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "test_runner.h"
- #include <functional>
- #include <memory>
- #include <sstream>
- #include <stdexcept>
- #include <string>
- #include <vector>
- using namespace std;
- struct Email {
- string from;
- string to;
- string body;
- };
- class Worker {
- public:
- virtual ~Worker() = default;
- virtual void Process(unique_ptr<Email> email) = 0;
- virtual void Run() {
- throw logic_error("Unimplemented");
- }
- protected:
- void PassOn(unique_ptr<Email> email) const {
- if (next) next->Process (move (email));
- }
- public:
- void SetNext(unique_ptr<Worker> next_) {
- next = move (next_);
- }
- private:
- unique_ptr<Worker> next;
- };
- class Reader : public Worker {
- public:
- explicit Reader (istream& in_) : in (in_) {}
- void Run () override {
- while (true) {
- unique_ptr<Email> email = make_unique<Email>();
- getline (in, email->from);
- getline (in, email->to);
- getline (in, email->body);
- if (!in) break;
- PassOn (move (email));
- }
- }
- void Process (unique_ptr <Email> email) override {}
- private:
- istream& in;
- };
- class Filter : public Worker {
- public:
- using Function = function<bool(const Email&)>;
- public:
- explicit Filter (Function f_) : f (move (f_)) {}
- void Process (unique_ptr<Email> email) override {
- if (f (*email)) {
- PassOn (move (email));
- }
- }
- private:
- Function f;
- };
- class Copier : public Worker {
- public:
- explicit Copier (string to_) : to (move (to_)) {}
- void Process (unique_ptr <Email> email) override {
- unique_ptr <Email> email_copy;
- if (email->to != to) {
- email_copy = make_unique<Email>(*email);
- email_copy->to = to;
- }
- PassOn (move (email));
- if (email_copy) PassOn (move (email_copy));
- }
- private:
- string to;
- };
- class Sender : public Worker {
- public:
- explicit Sender (ostream& out_) : out (out_) {}
- void Process (unique_ptr <Email> email) override {
- out << email->from << '\n' << email->to << '\n' << email->body << '\n';
- PassOn (move (email));
- }
- private:
- ostream& out;
- };
- class PipelineBuilder {
- public:
- explicit PipelineBuilder(istream& in) {
- v.emplace_back (make_unique<Reader>(in));
- }
- PipelineBuilder& FilterBy(Filter::Function filter_) {
- v.emplace_back (make_unique<Filter>(move (filter_)));
- return *this;
- }
- PipelineBuilder& CopyTo(string recipient) {
- v.emplace_back (make_unique<Copier>(move (recipient)));
- return *this;
- }
- PipelineBuilder& Send(ostream& out) {
- v.emplace_back (make_unique<Sender> (out));
- return *this;
- }
- unique_ptr<Worker> Build() {
- for (int i = (int)v.size () - 2; i >= 0; --i) v[i]->SetNext (move (v[i + 1]));
- return move (v.front ());
- }
- private:
- vector<unique_ptr<Worker>> v;
- };
- void TestSanity() {
- string input = (
- "erich@example.com\n"
- "richard@example.com\n"
- "Hello there\n"
- "erich@example.com\n"
- "ralph@example.com\n"
- "Are you sure you pressed the right button?\n"
- "ralph@example.com\n"
- "erich@example.com\n"
- "I do not make mistakes of that kind\n"
- );
- istringstream inStream(input);
- ostringstream outStream;
- PipelineBuilder builder(inStream);
- builder.FilterBy([](const Email& email) {
- return email.from == "erich@example.com";
- });
- builder.CopyTo("richard@example.com");
- builder.Send(outStream);
- auto pipeline = builder.Build();
- pipeline->Run();
- string expectedOutput = (
- "erich@example.com\n"
- "richard@example.com\n"
- "Hello there\n"
- "erich@example.com\n"
- "ralph@example.com\n"
- "Are you sure you pressed the right button?\n"
- "erich@example.com\n"
- "richard@example.com\n"
- "Are you sure you pressed the right button?\n"
- );
- ASSERT_EQUAL(expectedOutput, outStream.str());
- }
- //int main() {
- // TestRunner tr;
- // RUN_TEST(tr, TestSanity);
- // return 0;
- //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement