让nlohmann json支持std::wstring和嵌套结构的序列化与反序列化

xingyun86 10月前 852

让nlohmann json支持std::wstring和嵌套结构的序列化与反序列化

nlohmann json是一个star很高的C++ json解析库。

要让nlohmann json支持某个类型T,只要给这个类型T实现一个偏特化的struct adl_serializer<T>即可。adl_serializer是这个库里面针对泛型T预定义的适配器。

对于std::optional,也是要增加偏特化。

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;
        }
    }
 
    static void from_json(const json& j, std::optional<T>& opt) {
        if (j.is_null()) {
            opt = std::nullopt;
        } else {
            opt = j.get<T>();
        }
    }
};

 而嵌套结构,本身就支持的。使用预定义的宏NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE,可以免去自己针对每个类型T要实现其from_json/to_json函数。

 

下面是一个例子,适用于VC++。里面UTF-8和UTF-16的转换可以自行换成其他的实现方式。

#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING 
#include <string>
#include <codecvt>
#include <locale>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
namespace nlohmann {
    template <>
    struct adl_serializer<std::wstring> {
        static void to_json(json& j, const std::wstring& str) {
            std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
            j = converter.to_bytes(str);
        }
        static void from_json(const json& j, std::wstring& str) {
            std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
            str = converter.from_bytes(j.get<std::string>());
        }
    };
}
namespace ns {
    struct Address {
        std::wstring country;
        std::wstring province;
        std::wstring city;
    };
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Address, country, province, city)
    struct Person {
        std::wstring name;
        Address address;
        int age;
    };
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Person, name, address, age)
}
int main(int argc, char* argv[], char* envp)
{
    ns::Person p{ L"匿名", { L"中国", L"湖北", L"武汉" }, 60 };
    json j = p;
    const auto s = j.dump();
    auto p2 = j.template get<ns::Person>();
    return 0;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回