среда, 19 мая 2021 г.

[prog.c++] Больше шаблонов богу шаблонов: детали реализации неоднозначной фичи, которая может стать частью json-dto

Где-то пять лет назад мы сделали небольшую библиотеку-обертку над RapidJSON: json-dto. Целью было снизить количество писанины при работе RapidJSON. Вроде бы у нас получилось:

#include <json_dto/pub.hpp>

#include <deque>
#include <set>
#include <map>

struct my_message {
   std::deque<int> ids_;
   std::set<std::string> tags_;
   std::map<std::string, some_another_type> props_;
   ...
   template<typename Json_Io>
   void json_io(Json_Io & io) {
      io & json_dto::mandatory("ids", ids_)
         & json_dto::mandatory("tags", tags_)
         & json_dto::mandatory("properties", props_)
         ...
         ;
   }
};

Библиотека открытая, но про нее мало кто знает. Тем удивительнее, ей пользуется еще кто-то кроме нас. По крайней до сих пор приходят запросы на добавление той или иной фичи в json-dto.

На прошлой неделе возник один такой запрос. Достаточно необычный. В очередной раз доказывающий, что если библиотека используется, то рано или поздно она начнет использоваться так, как ты даже и не подозревал.

Человек захотел, чтобы можно было описывать поля объекта, которые подлежат только сериализации. Т.е. они участвуют при записи в JSON, а вот при десериализации из JSON их значения должны игнорироваться. Автор этого запроса даже сделал PR с реализацией фичи, которую он хотел получить в json-dto. Однако, предложенный вариант мне не понравился.

Данный пост посвящен рассказу о том, почему же PR не был принят в json-dto, что захотелось получить мне и что в итоге удалось придумать.