URLPattern can accept the following use cases: new URLPattern(input) new URLPattern(input, baseURL) new URLPattern(input, options) new URLPattern(input, baseURL, options)
| 451 | // new URLPattern(input, options) |
| 452 | // new URLPattern(input, baseURL, options) |
| 453 | std::tuple<std::variant<std::string, ada::url_pattern_init, bool>, |
| 454 | std::optional<std::string>, std::optional<ada::url_pattern_options>> |
| 455 | parse_pattern_field(ondemand::array& patterns) { |
| 456 | // If no arguments have been passed let's assume it's an empty init. |
| 457 | if (patterns.count_elements().value() == 0) { |
| 458 | return {ada::url_pattern_init{}, {}, {}}; |
| 459 | } |
| 460 | |
| 461 | std::optional<ada::url_pattern_init> init_obj{}; |
| 462 | std::optional<std::string> init_str{}; |
| 463 | std::optional<std::string> base_url{}; |
| 464 | std::optional<ada::url_pattern_options> options{}; |
| 465 | |
| 466 | // In simdjson's On-Demand, we disallow the pattern array size, access element |
| 467 | // 0, access element 1... as it leads to inefficient code. Instead, we iterate |
| 468 | // over the array. |
| 469 | // The following can be used for debugging: |
| 470 | // std::cout << "parse_pattern_field" << patterns.raw_json().value()<< |
| 471 | // std::endl; patterns.reset(); // <==== Do not forget because raw_json() |
| 472 | // consumes the object!!! |
| 473 | size_t pattern_size = 0; // how many elements we have consumed. |
| 474 | patterns.reset(); |
| 475 | for (auto pattern : patterns) { |
| 476 | if (pattern_size == 0) { |
| 477 | // Init can be a string or an object. |
| 478 | if (pattern.type() == ondemand::json_type::string) { |
| 479 | // If get_string fails (e.g., due to broken surrogates like \uD83D |
| 480 | // \uDEB2), we return false to indicate this test case should be skipped |
| 481 | // or treated as expecting an error. |
| 482 | if (pattern.get_string(init_str)) { |
| 483 | return std::tuple(false, std::nullopt, std::nullopt); |
| 484 | } |
| 485 | } else { |
| 486 | EXPECT_TRUE(pattern.type() == ondemand::json_type::object); |
| 487 | ondemand::object object = pattern.get_object(); |
| 488 | auto init_result = parse_init(object); |
| 489 | // If JSON parsing failed (e.g., broken surrogates), skip this test |
| 490 | if (!init_result.has_value()) { |
| 491 | return std::tuple(false, std::nullopt, std::nullopt); |
| 492 | } |
| 493 | if (std::holds_alternative<ada::url_pattern_init>(*init_result)) { |
| 494 | init_obj = std::get<ada::url_pattern_init>(*init_result); |
| 495 | } else { |
| 496 | init_obj = ada::url_pattern_init{}; |
| 497 | options = std::get<ada::url_pattern_options>(*init_result); |
| 498 | return std::tuple(*init_obj, base_url, options); |
| 499 | } |
| 500 | } |
| 501 | } else if (pattern_size == 1) { |
| 502 | // The second value can be a base url or an option. |
| 503 | if (pattern.type() == ondemand::json_type::string) { |
| 504 | EXPECT_FALSE(pattern.get_string(base_url)); |
| 505 | } else { |
| 506 | EXPECT_TRUE(pattern.type() == ondemand::json_type::object); |
| 507 | ondemand::object object = pattern.get_object(); |
| 508 | options = parse_options(object); |
| 509 | } |
| 510 | } else if (pattern_size == 2) { |
no test coverage detected