| 551 | } |
| 552 | |
| 553 | void parse(Input& input, const std::string& input_str, bool geometry) { |
| 554 | // Input json object. |
| 555 | rapidjson::Document json_input; |
| 556 | |
| 557 | // Parsing input string to populate the input object. |
| 558 | if (json_input.Parse(input_str.c_str()).HasParseError()) { |
| 559 | const std::string error_msg = |
| 560 | std::format("{} (offset: {})", |
| 561 | rapidjson::GetParseError_En(json_input.GetParseError()), |
| 562 | json_input.GetErrorOffset()); |
| 563 | throw InputException(error_msg); |
| 564 | } |
| 565 | |
| 566 | // Main checks for valid json input. |
| 567 | if (!json_input.IsObject()) { |
| 568 | throw InputException("Input root is not an object."); |
| 569 | } |
| 570 | |
| 571 | if (!json_input.HasMember("vehicles") || !json_input["vehicles"].IsArray()) { |
| 572 | throw InputException("Invalid vehicles."); |
| 573 | } |
| 574 | if (json_input["vehicles"].Empty()) { |
| 575 | // This is tested upstream upon solving but we still need to do it |
| 576 | // here to access first vehicle and retrieve amount_size. |
| 577 | throw InputException("No vehicle defined."); |
| 578 | } |
| 579 | |
| 580 | const auto& first_vehicle = json_input["vehicles"][0]; |
| 581 | check_id(first_vehicle, "vehicle"); |
| 582 | const bool first_vehicle_has_capacity = |
| 583 | (first_vehicle.HasMember("capacity") && |
| 584 | first_vehicle["capacity"].IsArray() && !first_vehicle["capacity"].Empty()); |
| 585 | const unsigned amount_size = |
| 586 | first_vehicle_has_capacity ? first_vehicle["capacity"].Size() : 0; |
| 587 | |
| 588 | input.set_geometry(geometry); |
| 589 | |
| 590 | // Add all vehicles. |
| 591 | for (rapidjson::SizeType i = 0; i < json_input["vehicles"].Size(); ++i) { |
| 592 | auto& json_vehicle = json_input["vehicles"][i]; |
| 593 | |
| 594 | input.add_vehicle(get_vehicle(json_vehicle, amount_size)); |
| 595 | } |
| 596 | |
| 597 | if (json_input.HasMember("jobs")) { |
| 598 | if (!json_input["jobs"].IsArray()) { |
| 599 | throw InputException("Invalid jobs."); |
| 600 | } |
| 601 | |
| 602 | for (rapidjson::SizeType i = 0; i < json_input["jobs"].Size(); ++i) { |
| 603 | input.add_job(get_job(json_input["jobs"][i], amount_size)); |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | if (json_input.HasMember("shipments")) { |
| 608 | if (!json_input["shipments"].IsArray()) { |
| 609 | throw InputException("Invalid shipments."); |
| 610 | } |
no test coverage detected