| 508 | } |
| 509 | |
| 510 | Rv<Directive::Handle> |
| 511 | Config::load_directive(YAML::Node const &drtv_node) |
| 512 | { |
| 513 | YAML::Node key_node; |
| 514 | for (auto const &[key_name, key_value] : drtv_node) { |
| 515 | TextView name{key_name.Scalar()}; |
| 516 | auto &&[arg, arg_errata]{parse_arg(name)}; |
| 517 | if (!arg_errata.is_ok()) { |
| 518 | return std::move(arg_errata); |
| 519 | } |
| 520 | |
| 521 | // Ignorable keys in the directive. Currently just one, so hand code it. Make this better |
| 522 | // if there is ever more than one. |
| 523 | if (name == Global::DO_KEY) { |
| 524 | continue; |
| 525 | } |
| 526 | // See if this is in the factory. It's not an error if it's not, to enable adding extra |
| 527 | // keys to directives. First key that is in the factory determines the directive type. |
| 528 | // If none of the keys are in the factory, that's an error and is reported after the loop. |
| 529 | if (auto spot{_factory.find(name)}; spot != _factory.end()) { |
| 530 | auto &info = spot->second; |
| 531 | auto rtti = &_drtv_info[info._idx]; |
| 532 | |
| 533 | if (!info._hook_mask[IndexFor(this->current_hook())]) { |
| 534 | return Errata(S_ERROR, R"(Directive "{}" at {} is not allowed on hook "{}".)", name, drtv_node.Mark(), |
| 535 | this->current_hook()); |
| 536 | } |
| 537 | |
| 538 | // If this is the first use of the directive, do config level setup for the directive type. |
| 539 | if (rtti->_count == 0) { |
| 540 | info._cfg_init_cb(*this, rtti); |
| 541 | } |
| 542 | ++(rtti->_count); |
| 543 | |
| 544 | auto &&[drtv, drtv_errata]{info._load_cb(*this, rtti, drtv_node, name, arg, key_value)}; |
| 545 | if (!drtv_errata.is_ok()) { |
| 546 | drtv_errata.note(R"(While parsing directive at {}.)", drtv_node.Mark()); |
| 547 | return std::move(drtv_errata); |
| 548 | } |
| 549 | drtv->_rtti = rtti; |
| 550 | |
| 551 | return std::move(drtv); |
| 552 | } |
| 553 | } |
| 554 | return Errata(S_ERROR, R"(Directive at {} has no recognized tag.)", drtv_node.Mark()); |
| 555 | } |
| 556 | |
| 557 | Rv<Directive::Handle> |
| 558 | Config::parse_directive(YAML::Node const &drtv_node) |