| 16713 | } |
| 16714 | |
| 16715 | std::string generate_pattern_string( |
| 16716 | std::vector<url_pattern_part>& part_list, |
| 16717 | url_pattern_compile_component_options& options) { |
| 16718 | // Let result be the empty string. |
| 16719 | std::string result{}; |
| 16720 | // Let index list be the result of getting the indices for part list. |
| 16721 | // For each index of index list: |
| 16722 | for (size_t index = 0; index < part_list.size(); index++) { |
| 16723 | // Let part be part list[index]. |
| 16724 | auto part = part_list[index]; |
| 16725 | // Let previous part be part list[index - 1] if index is greater than 0, |
| 16726 | // otherwise let it be null. |
| 16727 | // TODO: Optimization opportunity. Find a way to avoid making a copy here. |
| 16728 | std::optional<url_pattern_part> previous_part = |
| 16729 | index == 0 ? std::nullopt : std::optional(part_list[index - 1]); |
| 16730 | // Let next part be part list[index + 1] if index is less than index list's |
| 16731 | // size - 1, otherwise let it be null. |
| 16732 | std::optional<url_pattern_part> next_part = |
| 16733 | index < part_list.size() - 1 ? std::optional(part_list[index + 1]) |
| 16734 | : std::nullopt; |
| 16735 | // If part's type is "fixed-text" then: |
| 16736 | if (part.type == url_pattern_part_type::FIXED_TEXT) { |
| 16737 | // If part's modifier is "none" then: |
| 16738 | if (part.modifier == url_pattern_part_modifier::none) { |
| 16739 | // Append the result of running escape a pattern string given part's |
| 16740 | // value to the end of result. |
| 16741 | result.append(escape_pattern_string(part.value)); |
| 16742 | continue; |
| 16743 | } |
| 16744 | // Append "{" to the end of result. |
| 16745 | result += "{"; |
| 16746 | // Append the result of running escape a pattern string given part's value |
| 16747 | // to the end of result. |
| 16748 | result.append(escape_pattern_string(part.value)); |
| 16749 | // Append "}" to the end of result. |
| 16750 | result += "}"; |
| 16751 | // Append the result of running convert a modifier to a string given |
| 16752 | // part's modifier to the end of result. |
| 16753 | result.append(convert_modifier_to_string(part.modifier)); |
| 16754 | continue; |
| 16755 | } |
| 16756 | // Let custom name be true if part's name[0] is not an ASCII digit; |
| 16757 | // otherwise false. |
| 16758 | bool custom_name = !unicode::is_ascii_digit(part.name[0]); |
| 16759 | // Let needs grouping be true if at least one of the following are true, |
| 16760 | // otherwise let it be false: |
| 16761 | // - part's suffix is not the empty string. |
| 16762 | // - part's prefix is not the empty string and is not options's prefix code |
| 16763 | // point. |
| 16764 | bool needs_grouping = |
| 16765 | !part.suffix.empty() || |
| 16766 | (!part.prefix.empty() && part.prefix[0] != options.get_prefix()[0]); |
| 16767 | |
| 16768 | // If all of the following are true: |
| 16769 | // - needs grouping is false; and |
| 16770 | // - custom name is true; and |
| 16771 | // - part's type is "segment-wildcard"; and |
| 16772 | // - part's modifier is "none"; and |
no test coverage detected