简体   繁体   English

是否可以使用Boost.Hana反序列化?

[英]Is it possible to deserialize using Boost.Hana?

I'm getting started with Boost.Hana and was wondering if there is a way to deserialize back into a Struct that is known to Boost.Hana. 我开始使用Boost.Hana,并想知道是否有一种方法可以反序列化为Boost.Hana已知的Struct。 I know it's pretty simple to serialize such a Struct into a json string for example, but i did not find any information about the other way around. 我知道将这样的struct序列化为json字符串非常简单,但是我没有找到任何关于反过来的信息。 Is it currently just not possible to deserialize data with Boost.Hana or am i missing something? 目前是不是可以用Boost.Hana反序列化数据或者我错过了什么?

Hana is a metaprogramming library. Hana是一个元编程库。 It provides tools that can be used to build more complex functionality like serialization, but it does not provide such functionality itself. 它提供的工具可用于构建更复杂的功能,如序列化,但它本身不提供此类功能。 It's simply not the scope of that library. 它根本不是该库的范围。 Also, regarding your particular use case; 另外,关于您的特定用例; parsing is not an easy problem and other libraries like Boost.Spirit already try to solve it. 解析不是一个容易的问题,像Boost.Spirit这样的其他库已经尝试解决它。

That being said, I sketched an example of using Hana to deserialize JSON. 话虽这么说,我勾勒出一个使用Hana反序列化JSON的例子。 The result is neither efficient nor robust, but it should be enough to give you a glimpse at how Hana could be used to achieve something better. 结果既不高效也不健壮,但它应该足以让你一睹Hana如何用来实现更好的目标。 Solving this problem correctly would require implementing a parser combinator library à-la Boost.Spirit, which I won't do here. 正确解决这个问题需要实现一个解析器组合库à-la Boost.Spirit,我不会在这里做。 Here you go: 干得好:

template <typename T>
  std::enable_if_t<std::is_same<T, int>::value,
T> from_json(std::istream& in) {
    T result;
    in >> result;
    return result;
}

template <typename T>
  std::enable_if_t<std::is_same<T, std::string>::value,
T> from_json(std::istream& in) {
    char quote;
    in >> quote;

    T result;
    char c;
    while (in.get(c) && c != '"') {
        result += c;
    }
    return result;
}


template <typename T>
  std::enable_if_t<hana::Struct<T>::value,
T> from_json(std::istream& in) {
    T result;
    char brace;
    in >> brace;

    hana::for_each(hana::keys(result), [&](auto key) {
        in.ignore(std::numeric_limits<std::streamsize>::max(), ':');
        auto& member = hana::at_key(result, key);
        using Member = std::remove_reference_t<decltype(member)>;
        member = from_json<Member>(in);
    });
    in >> brace;
    return result;
}

template <typename Xs>
  std::enable_if_t<hana::Sequence<Xs>::value,
Xs> from_json(std::istream& in) {
    Xs result;
    char bracket;
    in >> bracket;
    hana::length(result).times.with_index([&](auto i) {
        if (i != 0u) {
            char comma;
            in >> comma;
        }

        auto& element = hana::at(result, i);
        using Element = std::remove_reference_t<decltype(element)>;
        element = from_json<Element>(in);
    });
    in >> bracket;
    return result;
}

And then you can use it like 然后你可以像使用它一样

struct Car {
    BOOST_HANA_DEFINE_STRUCT(Car,
        (std::string, brand),
        (std::string, model)
    );
};

struct Person {
    BOOST_HANA_DEFINE_STRUCT(Person,
        (std::string, name),
        (std::string, last_name),
        (int, age)
    );
};

int main() {
    std::istringstream json(R"EOS(
        [
            {
                "name": "John",
                "last_name": "Doe",
                "age": 30
            },
            {
                "brand": "BMW",
                "model": "Z3"
            },
            {
                "brand": "Audi",
                "model": "A4"
            }
        ]
    )EOS");

    auto actual = from_json<hana::tuple<Person, Car, Car>>(json);

    auto expected = hana::make_tuple(Person{"John", "Doe", 30},
                                     Car{"BMW", "Z3"},
                                     Car{"Audi", "A4"});

    assert(actual == expected);
}

The full example is available here . 完整的示例可在此处获得

The boost::hana json encoder is not compelete (it doesn't escape quotes for example): http://www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/index.html#tutorial-introspection-json boost :: hana json编码器不具备竞争力(例如,它没有逃避引用): http//www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/index.html#tutorial -introspection-JSON

To de-serialize, I'd use boost::spirit::x3 : http://ciere.com/cppnow15/x3_docs/index.html 要反序列化,我会使用boost :: spirit :: x3http//ciere.com/cppnow15/x3_docs/index.html

They have a json deserializer example: https://github.com/cierelabs/json_spirit 他们有一个json反序列化器示例: https//github.com/cierelabs/json_spirit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM