JayBeams  0.1
Another project to have fun coding.
merge_yaml.cpp
Go to the documentation of this file.
1 #include "jb/merge_yaml.hpp"
2 
3 #include <jb/assert_throw.hpp>
4 
5 void jb::yaml::merge_node(YAML::Node target, YAML::Node const& source) {
6  switch (source.Type()) {
7  case YAML::NodeType::Scalar:
8  target = source.Scalar();
9  break;
10  case YAML::NodeType::Map:
11  merge_map(target, source);
12  break;
13  case YAML::NodeType::Sequence:
14  merge_sequences(target, source);
15  break;
16  case YAML::NodeType::Null:
17  throw std::runtime_error("merge_node: Null source nodes not supported");
18  case YAML::NodeType::Undefined:
19  throw std::runtime_error(
20  "merge_node: Undefined source nodes not supported");
21  }
22 }
23 
24 void jb::yaml::merge_map(YAML::Node target, YAML::Node const& source) {
25  for (auto const& j : source) {
26  merge_node(target[j.first.Scalar()], j.second);
27  }
28 }
29 
30 void jb::yaml::merge_sequences(YAML::Node target, YAML::Node const& source) {
31  for (std::size_t i = 0; i != source.size(); ++i) {
32  if (i < target.size()) {
33  merge_node(target[i], source[i]);
34  } else {
35  target.push_back(YAML::Clone(source[i]));
36  }
37  }
38 }
39 
40 void jb::yaml::merge(class_overrides& by_class, YAML::Node node) {
41  // Only Map nodes can override by-class values ...
42  if (not node.IsMap()) {
43  return;
44  }
45  // ... iterate over the node, searching for nodes with a key starting
46  // with ':' ...
47  for (auto i : node) {
48  // ... the node is a map, there should be keys for all sub nodes ...
49  JB_ASSERT_THROW(i.first);
50  // ... found a key, check the format ...
51  std::string key = i.first.as<std::string>();
52  if (key[0] != ':') {
53  continue;
54  }
55  // ... try to insert into the map ...
56  auto ins = by_class.emplace(key, i.second);
57  if (ins.second == true) {
58  // ... good insert, nothing left to do ...
59  continue;
60  }
61  // ... okay there was a node for the class in the map already,
62  // need to merge the values ...
63  merge_node(ins.first->second, i.second);
64  }
65 }
66 
68  class_overrides tmp;
69  for (auto const& i : by_class) {
70  tmp.emplace(i.first, YAML::Clone(i.second));
71  }
72  return tmp;
73 }
class_overrides clone(class_overrides const &by_class)
Recursively clone all the overrides in by_class.
Definition: merge_yaml.cpp:67
void merge(class_overrides &by_class, YAML::Node source)
Merge the class-overrides from source into by_class.
Definition: merge_yaml.cpp:40
std::map< std::string, YAML::Node > class_overrides
Store the overrides for each class.
Definition: merge_yaml.hpp:17
void merge_sequences(YAML::Node target, YAML::Node const &source)
Memberwise merge two sequences, from source into target.
Definition: merge_yaml.cpp:30
void merge_map(YAML::Node target, YAML::Node const &source)
Merge all the values from source into target.
Definition: merge_yaml.cpp:24
#define JB_ASSERT_THROW(PRED)
void merge_node(YAML::Node target, YAML::Node const &source)
Merge two YAML nodes.
Definition: merge_yaml.cpp:5