// // cli.h // tax-manager // // Created by Sam Jaffe on 10/8/20. // Copyright © 2020 Sam Jaffe. All rights reserved. // #pragma once #include #include #include #include #include #include #include "lambda_cast.h" namespace cli { class cli { public: using args_t = std::vector; using callback = std::function; private: std::istream &in_; std::string prompt_; std::unordered_map arguments_; std::unordered_map callbacks_; bool eof_; public: cli(std::string const & prompt, std::istream &in = std::cin); cli(std::istream &in = std::cin); template cli & register_callback(std::string const & handle, std::function cb); template cli & register_callback(std::string const & handle, F && cb) { return register_callback(handle, lambdas::FFL(cb)); } void run() const; template static auto from_string(std::string const & value) { using E = std::tuple_element_t; using V = std::remove_cv_t>; return from_string(value); } private: bool active() const; template static T from_string(std::string const &); }; template void cli_invoke(std::function cb, cli::args_t const & args, std::index_sequence) { using tuple = std::tuple; cb(cli::from_string(args[Is])...); } template cli & cli::register_callback(std::string const & handle, std::function cb) { arguments_.emplace(handle, sizeof...(Args)); callbacks_.emplace(handle, [=](args_t const & args) { if (sizeof...(Args) > args.size()) { std::cerr << "Missing Args in command '" << handle << "', " << sizeof...(Args) << " required, but " << args.size() << " input\n"; return; } cli_invoke(cb, args, std::make_index_sequence()); }); return *this; } }