Last active
August 16, 2019 07:28
-
-
Save sandordargo/d3a1641e1e62c04d33d2ff76fae95329 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> | |
template <class T> | |
class Result { | |
public: | |
Result(std::shared_ptr<T> value, std::shared_ptr<std::exception> exc) : _value(std::make_tuple(value, exc)) {} | |
Result(std::shared_ptr<T> value) : _value(std::make_tuple(value, nullptr)) {} | |
Result(std::shared_ptr<std::exception> exc) : _value(std::make_tuple(nullptr, exc)) {} | |
bool isError() { | |
return std::get<1>(_value) != nullptr; | |
} | |
std::shared_ptr<std::exception> getError() { | |
return std::get<1>(_value); | |
} | |
std::shared_ptr<T> getValue() { | |
return std::get<0>(_value); | |
} | |
std::tuple<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<1>(body._value); | |
} | |
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