1//! @file console.hpp
2//! @author ryftchen
3//! @brief The declarations (console) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2025 ryftchen. All rights reserved.
6
7#pragma once
8
9#ifndef _PRECOMPILED_HEADER
10#include <readline/history.h>
11#include <readline/readline.h>
12#include <functional>
13#include <list>
14#include <memory>
15#else
16#include "application/pch/precompiled_header.hpp"
17#endif // _PRECOMPILED_HEADER
18
19//! @brief The application module.
20namespace application // NOLINT(modernize-concat-nested-namespaces)
21{
22//! @brief Console-mode-related functions in the application module.
23namespace console
24{
25//! @brief Console mode.
26class Console
27{
28public:
29 //! @brief Construct a new Console object.
30 //! @param greeting - default greeting information
31 explicit Console(const std::string_view greeting);
32 //! @brief Destroy the Console object.
33 virtual ~Console();
34 //! @brief Construct a new Console object.
35 Console(const Console&) = delete;
36 //! @brief Construct a new Console object.
37 Console(Console&&) = delete;
38 //! @brief The operator (=) overloading of Console class.
39 //! @return reference of the Console object
40 Console& operator=(const Console&) = delete;
41 //! @brief The operator (=) overloading of Console class.
42 //! @return reference of the Console object
43 Console& operator=(Console&&) = delete;
44
45 //! @brief Enumerate specific return code.
46 enum class RetCode : std::int8_t
47 {
48 //! @brief Quit.
49 quit = -1,
50 //! @brief Success.
51 success = 0,
52 //! @brief Error.
53 error = 1
54 };
55 //! @brief Alias for the container of arguments.
56 using Args = std::vector<std::string>;
57 //! @brief Alias for the callback of option.
58 using Callback = std::function<RetCode(const Args&)>;
59 //! @brief Register console option.
60 //! @param name - option name
61 //! @param description - option description
62 //! @param callback - callback function
63 void registerOption(const std::string_view name, const std::string_view description, Callback callback);
64 //! @brief Set greeting information.
65 //! @param greeting - greeting information
66 void setGreeting(const std::string_view greeting);
67 //! @brief Execute the target console option.
68 //! @param option - option to be executed
69 //! @return status of return code
70 [[nodiscard]] RetCode optionExecutor(const std::string& option) const;
71 //! @brief Execute all console options in the target file.
72 //! @param filename - file path to be executed
73 //! @return status of return code
74 [[nodiscard]] RetCode fileExecutor(const std::string& filename) const;
75 //! @brief Read console option line.
76 //! @return status of return code
77 RetCode readLine();
78
79private:
80 //! @brief Alias for the history state.
81 using HistoryState = ::HISTORY_STATE;
82 //! @brief Saved empty history state.
83 HistoryState* const emptyHistory{::history_get_history_state()};
84 //! @brief Terminal for interaction.
85 class Terminal
86 {
87 public:
88 //! @brief Construct a new Terminal object.
89 //! @param greeting - default greeting information
90 explicit Terminal(const std::string_view greeting) : greeting{greeting} {}
91 //! @brief Destroy the Terminal object.
92 virtual ~Terminal() { ::rl_free(history); }
93 //! @brief Construct a new Terminal object.
94 Terminal(const Terminal&) = delete;
95 //! @brief Construct a new Terminal object.
96 Terminal(Terminal&&) = delete;
97 //! @brief The operator (=) overloading of Terminal class.
98 //! @return reference of the Terminal object
99 Terminal& operator=(const Terminal&) = delete;
100 //! @brief The operator (=) overloading of Terminal class.
101 //! @return reference of the Terminal object
102 Terminal& operator=(Terminal&&) = delete;
103
104 //! @brief Greeting information.
105 std::string greeting;
106 //! @brief Alias for the map of option and callback in console.
107 using RegisteredOption = std::unordered_map<std::string, std::pair<std::string, Callback>>;
108 //! @brief Mapping table of all registered options.
109 RegisteredOption regTable;
110 //! @brief Register order.
111 std::list<std::string> orderList;
112 //! @brief Saved history state.
113 HistoryState* history{nullptr};
114 };
115 //! @brief Internal terminal.
116 const std::unique_ptr<Terminal> terminal;
117 //! @brief Dummy callback function.
118 const Callback dummyCallback{[](const Args& /*inputs*/) { return RetCode::success; }};
119
120 //! @brief Get all registered options with help information.
121 //! @return all registered options with help information
122 [[nodiscard]] auto getOptionHelpPairs() const;
123 //! @brief Set the default options.
124 void setDefaultOptions();
125 //! @brief Save current state.
126 void saveState();
127 //! @brief Reserve usage to the calling console instance.
128 void reserveConsole();
129
130 //! @brief Alias for the functor of option completer.
131 using OptionCompleterFunctor = char**(const char*, int, int);
132 //! @brief Alias for the functor of option compentry.
133 using OptionCompentryFunctor = char*(const char*, int);
134 //! @brief Get the option completer. Wrap the interface.
135 static OptionCompleterFunctor customCompleter;
136 //! @brief Get the option compentry. Wrap the interface.
137 static OptionCompentryFunctor customCompentry;
138};
139} // namespace console
140} // namespace application
141