Created
August 19, 2019 07:24
-
-
Save sandordargo/b3233f6f5d64c4990c93673fd6f00293 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <string> | |
#include <exception> | |
#include <numeric> | |
#include <functional> | |
#include <tuple> | |
#include <memory> | |
#include <variant> | |
template <class T> | |
class Result { | |
public: | |
Result(std::shared_ptr<T> value) : _value(value) {} | |
Result(std::shared_ptr<std::exception> exc) : _value(exc) {} | |
bool isError() { | |
return std::get_if<std::shared_ptr<std::exception>>(&_value) != nullptr; | |
} | |
std::shared_ptr<std::exception> getError() { | |
return std::get<std::shared_ptr<std::exception>>(_value); | |
} | |
std::shared_ptr<T> getValue() { | |
return std::get<std::shared_ptr<T>>(_value); | |
} | |
std::variant<std::shared_ptr<T>, std::shared_ptr<std::exception>> _value; | |
}; | |
class Input { | |
public: | |
Input() : Input(false) {} | |
Input(bool shouldThrow) : _shouldThrow(shouldThrow), _values({"an recepient", "a subject", "a body"}) { | |
} | |
auto read() -> Result<std::vector<std::string>> { | |
if (_shouldThrow) {return Result<std::vector<std::string>>(std::make_shared<std::exception>());} | |
return Result<std::vector<std::string>>(std::make_shared<std::vector<std::string>>(_values)); | |
} | |
private: | |
bool _shouldThrow; | |
std::vector<std::string> _values; | |
}; | |
class Parser { | |
public: | |
Parser() : Parser(false) {} | |
Parser(bool shouldThrow) : _shouldThrow(shouldThrow){} | |
auto parse(Result<std::vector<std::string>> input) -> Result<std::string> { | |
if (input.isError()) {return Result<std::string>(input.getError());} | |
if (_shouldThrow) { | |
return Result<std::string>(std::make_shared<std::runtime_error>("parser"));} | |
auto str = std::accumulate(std::begin(*input.getValue()), std::end(*input.getValue()), std::string(""), [](std::string a, std::string b){return a+" " + b;}); | |
return Result<std::string>(std::make_shared<std::string>(str)); | |
} | |
private: | |
bool _shouldThrow; | |
}; | |
class Email { | |
public: | |
Email(const Result<std::string>& x) : body(x){} | |
bool isValid() { | |
return std::get_if<1>(&body._value) == nullptr; | |
} | |
std::string getBody() { | |
return *std::get<0>(body._value); | |
} | |
std::shared_ptr<std::exception> getError() { | |
return std::get<1>(body._value); | |
} | |
private: | |
Result<std::string> body; | |
}; | |
auto send(Email email) -> bool { | |
if (!email.isValid()) { | |
std::cout << "email cannot be sent: " << email.getError()->what() << std::endl; | |
return false; | |
} | |
std::cout << "email sent: " << email.getBody() << std::endl; | |
return true; | |
} | |
int main () { | |
Input input{}; | |
Parser parser{}; | |
auto parsed = parser.parse(input.read()); | |
Email email{parsed}; | |
bool res = send(email); | |
Input input2{true}; | |
Parser parser2{}; | |
auto parsed2 = parser2.parse(input2.read()); | |
Email email2{parsed2}; | |
bool res2 = send(email2); | |
Parser parser3{true}; | |
auto parsed3 = parser3.parse(input.read()); | |
Email email3{parsed3}; | |
bool res3 = send(email3); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment