| 988 | } |
| 989 | |
| 990 | std::string generate_pattern_string( |
| 991 | std::vector<url_pattern_part>& part_list, |
| 992 | url_pattern_compile_component_options& options) { |
| 993 | // Let result be the empty string. |
| 994 | std::string result{}; |
| 995 | // Let index list be the result of getting the indices for part list. |
| 996 | // For each index of index list: |
| 997 | for (size_t index = 0; index < part_list.size(); index++) { |
| 998 | // Let part be part list[index]. |
| 999 | // Use reference to avoid copy |
| 1000 | const auto& part = part_list[index]; |
| 1001 | // Let previous part be part list[index - 1] if index is greater than 0, |
| 1002 | // otherwise let it be null. |
| 1003 | // Use pointer to avoid copy |
| 1004 | const url_pattern_part* previous_part = |
| 1005 | index == 0 ? nullptr : &part_list[index - 1]; |
| 1006 | // Let next part be part list[index + 1] if index is less than index list's |
| 1007 | // size - 1, otherwise let it be null. |
| 1008 | const url_pattern_part* next_part = |
| 1009 | index < part_list.size() - 1 ? &part_list[index + 1] : nullptr; |
| 1010 | // If part's type is "fixed-text" then: |
| 1011 | if (part.type == url_pattern_part_type::FIXED_TEXT) { |
| 1012 | // If part's modifier is "none" then: |
| 1013 | if (part.modifier == url_pattern_part_modifier::none) { |
| 1014 | // Append the result of running escape a pattern string given part's |
| 1015 | // value to the end of result. |
| 1016 | result.append(escape_pattern_string(part.value)); |
| 1017 | continue; |
| 1018 | } |
| 1019 | // Append "{" to the end of result. |
| 1020 | result += "{"; |
| 1021 | // Append the result of running escape a pattern string given part's value |
| 1022 | // to the end of result. |
| 1023 | result.append(escape_pattern_string(part.value)); |
| 1024 | // Append "}" to the end of result. |
| 1025 | result += "}"; |
| 1026 | // Append the result of running convert a modifier to a string given |
| 1027 | // part's modifier to the end of result. |
| 1028 | result.append(convert_modifier_to_string(part.modifier)); |
| 1029 | continue; |
| 1030 | } |
| 1031 | // Let custom name be true if part's name[0] is not an ASCII digit; |
| 1032 | // otherwise false. |
| 1033 | bool custom_name = !unicode::is_ascii_digit(part.name[0]); |
| 1034 | // Let needs grouping be true if at least one of the following are true, |
| 1035 | // otherwise let it be false: |
| 1036 | // - part's suffix is not the empty string. |
| 1037 | // - part's prefix is not the empty string and is not options's prefix code |
| 1038 | // point. |
| 1039 | bool needs_grouping = |
| 1040 | !part.suffix.empty() || |
| 1041 | (!part.prefix.empty() && !options.get_prefix().empty() && |
| 1042 | part.prefix[0] != options.get_prefix()[0]); |
| 1043 | |
| 1044 | // If all of the following are true: |
| 1045 | // - needs grouping is false; and |
| 1046 | // - custom name is true; and |
| 1047 | // - part's type is "segment-wildcard"; and |
no test coverage detected