| 10086 | |
| 10087 | template <url_pattern_encoding_callback F> |
| 10088 | tl::expected<std::vector<url_pattern_part>, errors> parse_pattern_string( |
| 10089 | std::string_view input, url_pattern_compile_component_options& options, |
| 10090 | F& encoding_callback) { |
| 10091 | ada_log("parse_pattern_string input=", input); |
| 10092 | // Let parser be a new pattern parser whose encoding callback is encoding |
| 10093 | // callback and segment wildcard regexp is the result of running generate a |
| 10094 | // segment wildcard regexp given options. |
| 10095 | auto parser = url_pattern_parser<F>( |
| 10096 | encoding_callback, generate_segment_wildcard_regexp(options)); |
| 10097 | // Set parser's token list to the result of running tokenize given input and |
| 10098 | // "strict". |
| 10099 | auto tokenize_result = tokenize(input, token_policy::strict); |
| 10100 | if (!tokenize_result) { |
| 10101 | ada_log("parse_pattern_string tokenize failed"); |
| 10102 | return tl::unexpected(tokenize_result.error()); |
| 10103 | } |
| 10104 | parser.tokens = std::move(*tokenize_result); |
| 10105 | |
| 10106 | // While parser's index is less than parser's token list's size: |
| 10107 | while (parser.can_continue()) { |
| 10108 | // Let char token be the result of running try to consume a token given |
| 10109 | // parser and "char". |
| 10110 | auto char_token = parser.try_consume_token(token_type::CHAR); |
| 10111 | // Let name token be the result of running try to consume a token given |
| 10112 | // parser and "name". |
| 10113 | auto name_token = parser.try_consume_token(token_type::NAME); |
| 10114 | // Let regexp or wildcard token be the result of running try to consume a |
| 10115 | // regexp or wildcard token given parser and name token. |
| 10116 | auto regexp_or_wildcard_token = |
| 10117 | parser.try_consume_regexp_or_wildcard_token(name_token); |
| 10118 | // If name token is not null or regexp or wildcard token is not null: |
| 10119 | if (name_token || regexp_or_wildcard_token) { |
| 10120 | // Let prefix be the empty string. |
| 10121 | std::string prefix{}; |
| 10122 | // If char token is not null then set prefix to char token's value. |
| 10123 | if (char_token) prefix = char_token->value; |
| 10124 | // If prefix is not the empty string and not options's prefix code point: |
| 10125 | if (!prefix.empty() && prefix != options.get_prefix()) { |
| 10126 | // Append prefix to the end of parser's pending fixed value. |
| 10127 | parser.pending_fixed_value.append(prefix); |
| 10128 | // Set prefix to the empty string. |
| 10129 | prefix.clear(); |
| 10130 | } |
| 10131 | // Run maybe add a part from the pending fixed value given parser. |
| 10132 | if (auto error = parser.maybe_add_part_from_the_pending_fixed_value()) { |
| 10133 | ada_log("maybe_add_part_from_the_pending_fixed_value failed"); |
| 10134 | return tl::unexpected(*error); |
| 10135 | } |
| 10136 | // Let modifier token be the result of running try to consume a modifier |
| 10137 | // token given parser. |
| 10138 | auto modifier_token = parser.try_consume_modifier_token(); |
| 10139 | // Run add a part given parser, prefix, name token, regexp or wildcard |
| 10140 | // token, the empty string, and modifier token. |
| 10141 | if (auto error = |
| 10142 | parser.add_part(prefix, name_token, regexp_or_wildcard_token, "", |
| 10143 | modifier_token)) { |
| 10144 | ada_log("parser.add_part failed"); |
| 10145 | return tl::unexpected(*error); |
no test coverage detected