cli.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // cli.h
  3. // tax-manager
  4. //
  5. // Created by Sam Jaffe on 10/8/20.
  6. // Copyright © 2020 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <functional>
  10. #include <iostream>
  11. #include <string>
  12. #include <tuple>
  13. #include <unordered_map>
  14. #include <vector>
  15. #include "lambda_cast.h"
  16. namespace cli {
  17. class cli {
  18. public:
  19. using args_t = std::vector<std::string>;
  20. using callback = std::function<void(args_t const &)>;
  21. private:
  22. std::istream &in_;
  23. std::unordered_map<std::string, callback> callbacks_;
  24. bool eof_;
  25. public:
  26. cli(std::istream &in = std::cin);
  27. template <typename... Args>
  28. cli & register_callback(std::string const & handle,
  29. std::function<void(Args...)> cb);
  30. template <typename F>
  31. cli & register_callback(std::string const & handle, F && cb) {
  32. return register_callback(handle, lambdas::FFL(cb));
  33. }
  34. void run() const;
  35. template <typename T> static T from_string(std::string const &);
  36. };
  37. template <typename... Args, size_t... Is>
  38. void cli_invoke(std::function<void(Args...)> cb, cli::args_t const & args,
  39. std::index_sequence<Is...>) {
  40. using tuple = std::tuple<Args...>;
  41. cb(cli::from_string<std::tuple_element_t<Is, tuple>>(args[Is])...);
  42. }
  43. template <typename... Args>
  44. cli & cli::register_callback(std::string const & handle,
  45. std::function<void(Args...)> cb) {
  46. callbacks_.emplace(handle, [=](args_t const & args) {
  47. if (sizeof...(Args) > args.size()) {
  48. std::cerr << "Missing Args in command '" << handle << "', " <<
  49. sizeof...(Args) << " required, but " << args.size() << " input\n";
  50. return;
  51. }
  52. cli_invoke(cb, args, std::make_index_sequence<sizeof...(Args)>());
  53. });
  54. return *this;
  55. }
  56. }