|
1 | 1 | #pragma once |
2 | 2 | #include <meta> |
| 3 | +#include <rsl/constexpr_assert> |
3 | 4 | #include <rsl/meta_traits> |
4 | 5 | #include <vector> |
5 | 6 | #include <string_view> |
@@ -104,19 +105,32 @@ struct Option { |
104 | 105 | rsl::string_view name; |
105 | 106 | rsl::string_view description; |
106 | 107 | rsl::span<Parameter const> parameters; |
| 108 | + char shorthand = '\0'; |
107 | 109 | bool run_early = false; |
108 | 110 | bool is_flag = false; |
109 | 111 |
|
110 | 112 | std::optional<Unevaluated> parse(ArgParser& parser) { |
111 | 113 | auto opt_name = parser.current(); |
112 | | - if (!opt_name.starts_with("--")) { |
| 114 | + if (!opt_name.starts_with('-')) { |
113 | 115 | return {}; |
114 | 116 | } |
115 | 117 |
|
116 | | - opt_name.remove_prefix(2); |
117 | | - if (opt_name != name) { |
118 | | - return {}; |
| 118 | + opt_name.remove_prefix(1); |
| 119 | + if (!opt_name.starts_with('-')) { |
| 120 | + if (opt_name.size() != 1) { |
| 121 | + return {}; |
| 122 | + } |
| 123 | + |
| 124 | + if (opt_name[0] != shorthand) { |
| 125 | + return {}; |
| 126 | + } |
| 127 | + } else { |
| 128 | + opt_name.remove_prefix(1); |
| 129 | + if (opt_name != name) { |
| 130 | + return {}; |
| 131 | + } |
119 | 132 | } |
| 133 | + |
120 | 134 | ++parser.cursor; // parser will not unwind after this point |
121 | 135 |
|
122 | 136 | Unevaluated option{.handle = _impl_handler}; |
@@ -152,6 +166,15 @@ struct Option { |
152 | 166 | description = std::define_static_string(desc->data); |
153 | 167 | } |
154 | 168 |
|
| 169 | + if (auto shorthand_tag = annotation_of_type<annotations::Shorthand>(reflection); |
| 170 | + shorthand_tag) { |
| 171 | + auto short_opt = shorthand_tag->data; |
| 172 | + if (short_opt.size() != 1) { |
| 173 | + compile_error("Shorthands need to be a single character"); |
| 174 | + } |
| 175 | + shorthand = short_opt[0]; |
| 176 | + } |
| 177 | + |
155 | 178 | if (meta::has_annotation<annotations::Flag>(reflection)) { |
156 | 179 | is_flag = true; |
157 | 180 | } |
|
0 commit comments