Мне нужно проанализировать некоторые YAML в C ++ (вроде newi sh в YAML). Я ищу использовать yaml- cpp. Мои цели:
- Создать несколько общих / многократно используемых утилит для помощи в разборе этого YAML.
- Чтобы иметь возможность обновить YAML :: Node и / или добавить пропущенные значения (указав значения по умолчанию)
Если я возьму какой-нибудь пример YAML, он может выглядеть следующим образом:
...
comms:
messageBus:
remoteHost: "message-bus"
remotePort: 5672
или даже:
...
comms:
Тем не менее, Я хочу иметь возможность обновлять YAML, отражая значения по умолчанию. Таким образом, чтобы прочитать вышеупомянутый YAML, код будет выглядеть примерно так:
auto &nodeComms = get_yaml_node_field_or_insert(node, "comms");
auto &nodeMessageBus = get_yaml_node_field_or_insert(nodeComms , "comms");
auto strRemoteHost = get_yaml_string_field_or_default_and_update(nodeMessageBus, "remoteHost", "127.0.0.1");
auto nRemotePort = get_yaml_uint16_field_or_default_and_update(nodeMessageBus, "remotePort", uint16_t{5672});
, так что если приведенный выше код выполняется во втором примере, обновленный YAML теперь будет иметь вид:
...
comms:
messageBus:
remoteHost: "127.0.0.1"
remotePort: 5672
Для get_yaml_string_field_or_default_and_update
и get_yaml_uint16_field_or_default_and_update
довольно просто создать шаблонную функцию для обработки чтения различных типов значений и вставки их при необходимости:
///////////////////////////////////////////////////////////////////////////
template <typename TYPE_IN, typename TYPE_RETURN>
TYPE_RETURN get_type_from_yaml_node_or_default_and_update(YAML::Node &node,
const char *pchFieldName,
TYPE_IN nValueDefault) noexcept
{
if (!node)
{
assert(false);
throw std::runtime_error("Invalid node");
}
if (!node[pchFieldName])
{
node[pchFieldName] = nValueDefault;
return nValueDefault;
}
try
{
return node[pchFieldName].as<TYPE_RETURN>();
}
catch (const std::exception &e)
{
node[pchFieldName] = nValueDefault;
return nValueDefault;
}
catch (...)
{
node[pchFieldName] = nValueDefault;
return nValueDefault;
}
}
Код, с которым я борюсь, это get_yaml_node_field_or_insert
:
///////////////////////////////////////////////////////////////////////////
YAML::Node &get_yaml_node_field_or_insert(YAML::Node &node, const char *pchFieldName) noexcept
{
if (!node)
{
assert(false);
throw std::runtime_error("Invalid node");
}
// TODO: Either 1) Return reference if it exists or 2) insert if it does not and return reference.
return node[pchFieldName];
}
Похоже, что оператор [] не возвращает ссылку в соответствии с API.
// indexing
template <typename Key>
const Node operator[](const Key& key) const;
template <typename Key>
Node operator[](const Key& key);
Буду признателен за любые советы / предложения.