71 return Unexpected(BasicError::InvalidArgument);
73 args = *args.subspan(1);
76 seen_arguments.
fill(
false);
78 auto count_option_processed =
usize { 0 };
80 auto send_arg_to_back = [&](
usize i) {
82 count_option_processed++;
85 auto result = Base {};
86 for (
usize i = 0; i < args.size(); i++) {
87 auto arg_index = i - count_option_processed;
88 auto arg = args[arg_index];
91 if (!arg.starts_with(
'-')) {
96 if (arg ==
"--"_tsv) {
97 send_arg_to_back(arg_index);
102 if (!arg.starts_with(
"--"_tsv)) {
103 for (
usize char_index = 1; char_index < arg.size(); char_index++) {
104 auto index = lookup_short_name(arg[char_index]);
106 return Unexpected(BasicError::InvalidArgument);
110 if (option_boolean(*index)) {
111 DI_TRY(option_parse(*index, seen_arguments, &result, {}));
112 if (option_always_succeeds(*index)) {
119 auto value_view = arg.substr(arg.begin() +
isize(char_index + 1));
120 if (!value_view.empty()) {
121 DI_TRY(option_parse(*index, seen_arguments, &result, value_view));
122 if (option_always_succeeds(*index)) {
129 if (i + 1 >= args.size()) {
130 return Unexpected(BasicError::InvalidArgument);
134 DI_TRY(option_parse(*index, seen_arguments, &result, args[arg_index + 1]));
135 if (option_always_succeeds(*index)) {
138 send_arg_to_back(arg_index);
141 send_arg_to_back(arg_index);
146 auto equal = arg.find(
'=');
149 name = arg.
substr(arg.begin() + 2);
154 auto index = lookup_long_name(name);
156 return Unexpected(BasicError::InvalidArgument);
159 if (option_boolean(*index)) {
161 return Unexpected(BasicError::InvalidArgument);
163 DI_TRY(option_parse(*index, seen_arguments, &result, {}));
164 if (option_always_succeeds(*index)) {
167 send_arg_to_back(arg_index);
172 if (!
equal && i + 1 >= args.size()) {
173 return Unexpected(BasicError::InvalidArgument);
176 value = args[arg_index + 1];
177 send_arg_to_back(arg_index);
178 send_arg_to_back(arg_index);
181 value = arg.substr(
equal.end());
182 send_arg_to_back(arg_index);
185 DI_TRY(option_parse(*index, seen_arguments, &result, value));
186 if (option_always_succeeds(*index)) {
192 for (
usize i = 0; i < m_options.size(); i++) {
193 if (!seen_arguments[i] && option_required(i)) {
194 return Unexpected(BasicError::InvalidArgument);
199 auto positional_arguments = *args.subspan(0, args.size() - count_option_processed);
200 if (positional_arguments.size() < minimum_required_argument_count()) {
201 return Unexpected(BasicError::InvalidArgument);
204 auto argument_index =
usize(0);
205 for (
auto i =
usize(0); i < positional_arguments.size(); argument_index++) {
206 auto count_to_consume = !argument_variadic(i) ? 1 : positional_arguments.size() - argument_count() + 1;
207 auto input = *positional_arguments.subspan(i, count_to_consume);
208 DI_TRY(argument_parse(argument_index, &result, input));
209 i += count_to_consume;
218 constexpr auto header_effect = di::FormatEffect::Bold | di::FormatColor::Yellow;
219 constexpr auto program_effect = di::FormatEffect::Bold;
220 constexpr auto option_effect = di::FormatColor::Cyan;
221 constexpr auto option_value_effect = di::FormatColor::Green;
222 constexpr auto argument_effect = di::FormatColor::Green;
232 for (
auto const&
option : m_options) {
241 for (
auto const&
argument : m_arguments) {
246 if (!m_arguments.empty()) {
248 for (
auto const&
argument : m_arguments) {
254 if (!m_options.empty()) {
256 for (
auto const&
option : m_options) {
258 if (
option.short_name()) {