Stop the application on EOF

This commit is contained in:
Alexander Kobjolke 2023-04-18 22:15:40 +02:00
parent 0d42589648
commit 342c6069a2

View file

@ -6,25 +6,28 @@
#include <variant>
#include <thread>
#include <sstream>
#include <optional>
using namespace std::chrono_literals;
template <typename Message> struct ConsoleIO {
static auto ReadlineS(std::istream& is, std::function<Message(std::string)> f) {
static auto ReadlineS(std::istream& is, std::function<Message(std::optional<std::string>)> f) {
return [=,&is] {
std::string line;
std::getline(is, line);
return f(line);
if (std::string line; std::getline(is, line)) {
return f(std::make_optional(line));
} else {
return f(std::nullopt);
}
};
}
static std::function<Message()>
Readline(std::function<Message(std::string)> f) {
Readline(std::function<Message(std::optional<std::string>)> f) {
return ReadlineS (std::ref(std::cin), f);
}
static std::function<Message()>
Prompt(std::string prompt, std::function<Message(std::string)> f) {
Prompt(std::string prompt, std::function<Message(std::optional<std::string>)> f) {
return [=] {
std::cout << prompt << std::flush;
return Readline (f)();
@ -79,36 +82,53 @@ template <typename ModelT, typename MessageT> struct AppT {
// user defined
using Model = int;
struct SetState {
Model s;
struct Model {
bool done{false};
int value{0};
};
using Message = std::variant<SetState>;
struct SetValue {
int s;
};
struct Stop {
};
using Message = std::variant<SetValue, Stop>;
auto userInputToMsg(const std::optional<std::string>& s) -> Message {
if (s) {
std::stringstream sstr(*s);
int r;
sstr >> r;
return SetValue { r };
} else {
return Stop{};
}
auto strToState (const std::string& s) -> Message {
std::stringstream sstr(s);
int r;
sstr >> r;
return SetState { r };
}
int main() {
using App = AppT<int, Message>;
using App = AppT<Model, Message>;
App app;
return app.run(App::Config{
[]() -> App::InitResult {
return {23, {App::Console::Prompt("> ", strToState)}};
return {{false, 23}, {App::Console::Prompt("> ", userInputToMsg)}};
}, // init
[](const App::Model &state,
[](App::Model state,
const App::Message &msg) -> App::UpdateResult {
return {std::get<SetState>(msg).s,
{App::Console::Prompt("> ", strToState)}};
if (auto stop = std::get_if<Stop>(&msg); stop) {
state.done = true;
return {state, {}};
} else {
state.value = std::get<SetValue>(msg).s;
return {state, {App::Console::Prompt("> ", userInputToMsg)}};
}
}, // update
[](const App::Model &state) -> App::ViewResult {
return "Model " + std::to_string(state);
return "Model " + std::to_string(state.value);
}, // view
[](const App::Model &state) -> bool { return state == 42; } // done
[](const App::Model &state) -> bool { return state.done; } // done
});
}