Skip to content

Instantly share code, notes, and snippets.

@sandordargo
Created August 19, 2019 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sandordargo/b3233f6f5d64c4990c93673fd6f00293 to your computer and use it in GitHub Desktop.
Save sandordargo/b3233f6f5d64c4990c93673fd6f00293 to your computer and use it in GitHub Desktop.
#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