#include <iostream>
#include <fstream>
#include <vector>
#include <optional>
#include "json.hpp"
namespace nl = nlohmann;
enum class TestEnum : int {
左 = 0,
右
};
struct SubTestStruct {
int 测试 = 0;
};
struct TestStruct {
int 测试 = 0;
bool 测试Bool = false;
TestEnum 测试Enum = TestEnum::左;
std::optional<bool> 测试Opt;
std::vector<int> 测试Vec;
SubTestStruct 子测试结构体;
};
// nl 不直接支持 optional, 使用 adl_serializer 可以支持任意类型的序列化
// https://github.com/nlohmann/json/pull/2117
// https://github.com/nlohmann/json#how-do-i-convert-third-party-types
namespace nlohmann {
template <typename T>
struct adl_serializer<std::optional<T>> {
static void to_json(json& j, const std::optional<T>& opt) {
if (opt == std::nullopt) {
j = nullptr;
} else {
j = *opt; // this will call adl_serializer<T>::to_json which will
// find the free function to_json in T's namespace!
}
}
static void from_json(const json& j, std::optional<T>& opt) {
if (j.is_null()) {
opt = std::nullopt;
} else {
opt = j.get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
}
};
}
// 序列化struct,class
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SubTestStruct, 测试)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TestStruct, 测试, 测试Bool, 测试Enum, 测试Opt, 测试Vec, 子测试结构体)
// 序列化enum
NLOHMANN_JSON_SERIALIZE_ENUM(TestEnum, {
{TestEnum::左, "左"},
{TestEnum::右, "右"},
})
void 打印测试(const TestStruct& s) {
nl::json jsonValue;
nl::to_json(jsonValue, s);
std::cout << "TestStruct 测试: " << s.测试
<< ", 测试Bool: " << s.测试Bool
<< ", 测试Enum: " << (int) s.测试Enum
<< ", 测试Opt: " << (s.测试Opt.has_value() && s.测试Opt.value())
<< ", 测试Vec: { ";
for(auto val : s.测试Vec) {
std::cout << val << ",";
}
std::cout << "\b" << " }";
std::cout << ", 子测试结构体.测试: " << s.子测试结构体.测试;
std::cout << std::endl;
}
int main() {
// 写入
std::ofstream sf("config.json");
nl::json j;
TestStruct s;
s.测试 = 100;
s.测试Opt = true;
for(int i = 0; i < 5; ++i) {
s.测试Vec.push_back(i);
}
s.子测试结构体.测试 = 99;
打印测试(s);
nl::to_json(j, s);
// 单独获取一个值
std::cout << "Json value: " << j["测试"] << std::endl;
// 写入文件
sf << j;
sf.close();
// 读取
std::ifstream is("config.json");
nl::json readJson;
is >> readJson;
TestStruct newS = readJson.get<TestStruct>();
// nl::from_json(readJson, newS);
打印测试(newS);
is.close();
return 0;
}
注: nl_json 是一个 utf-8 only 库,中文下使用需要注意编码