可以使用 yaml-cpp 库的编码和解码接口,将结构体对象转换为 YAML 格式的字符串或将 YAML 格式的字符串转换为结构体对象。
下面是具体的代码实现:
#include <yaml-cpp/yaml.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
struct NsStore
{
std::string appId;
std::string clusterName;
std::string namespaceName;
std::string comment;
std::string format;
bool isPublic;
std::vector<std::map<std::string, std::string>> items;
std::string dataChangeCreatedBy;
std::string dataChangeLastModifiedBy;
std::string dataChangeCreatedTime;
std::string dataChangeLastModifiedTime;
};
namespace YAML
{
template <>
struct convert<NsStore>
{
static Node encode(const NsStore& store)
{
Node node;
node["appId"] = store.appId;
node["clusterName"] = store.clusterName;
node["namespaceName"] = store.namespaceName;
node["comment"] = store.comment;
node["format"] = store.format;
node["isPublic"] = store.isPublic;
node["dataChangeCreatedBy"] = store.dataChangeCreatedBy;
node["dataChangeLastModifiedBy"] = store.dataChangeLastModifiedBy;
node["dataChangeCreatedTime"] = store.dataChangeCreatedTime;
node["dataChangeLastModifiedTime"] = store.dataChangeLastModifiedTime;
Node items_node;
for (const auto& item : store.items)
{
Node item_node;
for (const auto& kv : item)
{
item_node[kv.first] = kv.second;
}
items_node.push_back(item_node);
}
node["items"] = items_node;
return node;
}
static bool decode(const Node& node, NsStore& store)
{
if (!node.IsMap())
{
return false;
}
store.appId = node["appId"].as<std::string>();
store.clusterName = node["clusterName"].as<std::string>();
store.namespaceName = node["namespaceName"].as<std::string>();
store.comment = node["comment"].as<std::string>();
store.format = node["format"].as<std::string>();
store.isPublic = node["isPublic"].as<bool>();
store.dataChangeCreatedBy = node["dataChangeCreatedBy"].as<std::string>();
store.dataChangeLastModifiedBy = node["dataChangeLastModifiedBy"].as<std::string>();
store.dataChangeCreatedTime = node["dataChangeCreatedTime"].as<std::string>();
store.dataChangeLastModifiedTime = node["dataChangeLastModifiedTime"].as<std::string>();
const auto& items_node = node["items"];
store.items.reserve(items_node.size());
for (const auto& item_node : items_node)
{
std::map<std::string, std::string> item;
for (const auto& kv : item_node)
{
item[kv.first.as<std::string>()] = kv.second.as<std::string>();
}
store.items.push_back(std::move(item));
}
return true;
}
};
}
int main()
{
try
{
NsStore store;
store.appId = "some-app-id";
store.clusterName = "some-cluster-name";
store.namespaceName = "some-namespace-name";
store.comment = "some-comment";
store.format = "some-format";
store.isPublic = true;
store.dataChangeCreatedBy = "some-user";
store.dataChangeLastModifiedBy = "some-user";
store.dataChangeCreatedTime = "2022-01-01T00:00:00Z";
store.dataChangeLastModifiedTime = "2022-01-02T00:00:00Z";
store.items.push_back({ {"key1", "value1"}, {"key2", "value2"} });
store.items.push_back({ {"key3", "value3"}, {"key4", "value4"} });
std::cout << "=== Encode ===\n";
std::cout << YAML::Dump(store) << "\n";
const std::string yaml_str =
"appId: some-app-id\n"
"clusterName: some-cluster-name\n"
"namespaceName: some-namespace-name\n"
"comment: some-comment\n"
"format: some-format\n"
"isPublic: true\n"
"items:\n"
" - {key1: value1, key2: value2}\n"
" - {key3: value3, key4: value4}\n"
"dataChangeCreatedBy: some-user\n"
"dataChangeLastModifiedBy: some-user\n"
"dataChangeCreatedTime: '2022-01-01T00:00:00Z'\n"
"dataChangeLastModifiedTime: '2022-01-02T00:00:00Z'\n";
std::cout << "=== Decode ===\n";
const YAML::Node node = YAML::Load(yaml_str);
NsStore store2;
if (node.IsDefined() && !node.IsNull())
{
store2 = node.as<NsStore>();
}
std::cout << "appId=" << store2.appId << "\n";
std::cout << "clusterName=" << store2.clusterName << "\n";
std::cout << "namespaceName=" << store2.namespaceName << "\n";
std::cout << "comment=" << store2.comment << "\n";
std::cout << "format=" << store2.format << "\n";
std::cout << "isPublic=" << store2.isPublic << "\n";
std::cout << "dataChangeCreatedBy=" << store2.dataChangeCreatedBy << "\n";
std::cout << "dataChangeLastModifiedBy=" << store2.dataChangeLastModifiedBy << "\n";
std::cout << "dataChangeCreatedTime=" << store2.dataChangeCreatedTime << "\n";
std::cout << "dataChangeLastModifiedTime=" << store2.dataChangeLastModifiedTime << "\n";
std::cout << "items:\n";
for (const auto& item : store2.items)
{
for (const auto& kv : item)
{
std::cout << " " << kv.first << "=" << kv.second << "\n";
}
}
}
catch (const YAML::Exception& ex)
{
std::cerr << ex.what() << "\n";
return 1;
}
return 0;
}