Smertig / banana

🍌 Modern C++ Telegram Bot API library
https://smertig.github.io/banana/master
MIT License
41 stars 4 forks source link

Making serialization isolated and extendable with custom types. #14

Closed Pilipets closed 3 years ago

Pilipets commented 3 years ago

The banana library already contains a well-structured serialization solution for telegram types - deser.hpp, meta.hpp, core.cpp and serialization.hpp, but the problem is with extensibility.

If a client uses the banana library and needs a serialization of custom types for some other non-telegram purposes, one needs to reimplement the whole serialization/deserialization again because of the banana design.

But what I noticed to be extremely beneficial is the ability to reuse and specify serializer behavior with custom-created types. Below I added the example of the desired functionality.

The client only creates the reflector stuff and reuses or extends(in terms of creating new struct serializer<T>:) logic of the banana library.

struct Temp {
    int64_t x, y;
    double z;
};
namespace banana {
    namespace meta {
        template <>
        struct reflector<Temp> {
            template <class F>
            static void for_each_field(F&& f) {
                f(string_view_t("x"), &Temp::x);
                f(string_view_t("y"), &Temp::y);
                f(string_view_t("z"), &Temp::z);
            }
        };
        template <>
        constexpr bool is_reflectable_v<Temp> = true;
        template <>
        constexpr string_view_t name_of<Temp>("Temp");
    }
    namespace deser {
        template optional_t<string_t> serialize<Temp>(Temp value);
    }
}

I agree that because of the template-based serialization, it's not easy to do. However, since you referred to some upcoming changes on the JSON-related part in another issue, I'd like this one to be taken into consideration as well. P. S. I mentioned only the serialization part here for simplicity but implied deserialization as well.

Let me know your thoughts here...

Smertig commented 3 years ago

I don't quite understand. Do you want to use banana as a serialization library? I don't think that it's good idea because banana's serializers are very stupid. Please, give an example what do you want to achieve.

Pilipets commented 3 years ago

Do you want to use banana as a serialization library?

In short, yes.

Details: Not purely as a serialization library, but for JSON-based serialization as well.

For example, I included banana in my project because of telegram-communication needs, and now I want to send/process JSON for my types and other purposes - why not reuse banana::deser::serialize(...) with custom types?

banana already does a pretty good job with serializing/deserializing optional, variant, other types specified here - https://github.com/Smertig/banana/blob/master/source/serialization.hpp.

What I want is to use that compact serialization solution from the banana for my classes and non-telegram-related purposes instead of taking another library. I created the class, specified the serialization behavior, and now can use banana::deser::serialize(...) and banana::deser::deserialize(...) to get JSON strings for whatever purposes.

But if it's not expected by design, then close the issue.

Smertig commented 3 years ago

JSON-serializer is not a part of public API, it's used only internally. I don't know how to allow extending serializer for user-defined types without exposing implementation details (namely, serialize_args<T> implementation that uses <nlohmann/json.hpp>).