| 625 | } |
| 626 | |
| 627 | Errata |
| 628 | Config::parse_yaml(YAML::Node root, TextView path) |
| 629 | { |
| 630 | static constexpr TextView ROOT_PATH{"."}; |
| 631 | // Walk the key path and find the target. If the path is the special marker for ROOT_PATH |
| 632 | // do not walk at all. |
| 633 | for (auto p = (path == ROOT_PATH ? TextView{} : path); p;) { |
| 634 | auto key{p.take_prefix_at('.')}; |
| 635 | if (auto node{root[key]}; node) { |
| 636 | root.reset(node); |
| 637 | } else { |
| 638 | return Errata(S_ERROR, R"(Key "{}" not found - no such key "{}".)", path, path.prefix(path.size() - p.size()).rtrim('.')); |
| 639 | } |
| 640 | } |
| 641 | |
| 642 | Errata errata; |
| 643 | |
| 644 | // Special case remap loading. |
| 645 | auto drtv_loader = &self_type::load_top_level_directive; // global loader. |
| 646 | if (_hook == Hook::REMAP) { // loading only remap directives. |
| 647 | drtv_loader = &self_type::load_remap_directive; |
| 648 | } |
| 649 | |
| 650 | if (root.IsSequence()) { |
| 651 | for (auto child : root) { |
| 652 | errata.note((this->*drtv_loader)(child)); |
| 653 | } |
| 654 | if (!errata.is_ok()) { |
| 655 | errata.note(R"(While loading list of top level directives for "{}" at {}.)", path, root.Mark()); |
| 656 | } |
| 657 | } else if (root.IsMap()) { |
| 658 | errata = (this->*drtv_loader)(root); |
| 659 | } else { |
| 660 | } |
| 661 | return errata; |
| 662 | }; |
| 663 | |
| 664 | Errata |
| 665 | Config::define(swoc::TextView name, HookMask const &hooks, Directive::InstanceLoader &&worker, |