USCiLab/cereal

Deserializing JSON using cereal

Opened this issue · 0 comments

I'm trying to get the cereal serialization library to emit string representations of enums. I'm using the magic_enum library to perform the conversions between the enum and string.

While I have no trouble serializing the given MyStruct to a JSON, it's deserialization causing the error.

#include <fmt/core.h>
#include <magic_enum.hpp>
#include <cereal/archives/json.hpp>
#include <fstream>

enum class EnumType : int {
    A, B, C
};

template<class Archive,
        cereal::traits::EnableIf<cereal::traits::is_text_archive<Archive>::value>
        = cereal::traits::sfinae, class T>
std::enable_if_t<std::is_enum_v<T>, std::string> save_minimal(Archive &, const T &h) {
    return std::string(magic_enum::enum_name(h));
}

template<class Archive, cereal::traits::EnableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae, class T>
std::enable_if_t<std::is_enum_v<T>, void> load_minimal(Archive const &, T &enumType, std::string const &str) {
    enumType = magic_enum::enum_cast<T>(str).value();
}
struct MyStruct {
    EnumType e;
    std::string s;

    // serialize
    template<class Archive>
    void serialize(Archive &archive) {
        archive(CEREAL_NVP(e), CEREAL_NVP(s));
    }
};

int main() {
    std::string json_file = "s.json";

    // serialize to JSON
    MyStruct s{EnumType::A, "xmcnbx"};
    std::ofstream os(json_file);
    cereal::JSONOutputArchive archive(os); // ok
    archive(s);

    // deserialize from JSON
    MyStruct s2;
    std::ifstream is(json_file);
    cereal::JSONInputArchive archive2(is); // error!
    archive2(s2);
    fmt::print("s2.e = {}, s2.s = {}", magic_enum::enum_name(s2.e), s2.s);
}

s.json (as expected)

{
    "value0": {
        "e": "A",
        "s": "xmcnbx"
    }
}

error message

libc++abi: terminating with uncaught exception of type cereal::RapidJSONException: rapidjson internal assertion failure: IsObject()

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)