SlideShare a Scribd company logo
1 of 94
Download to read offline
Упрощаем переход от
JSON к C++ структурам и
обратно
Николай Гродзицкий
О чем пойдет речь?
2
О чем пойдет речь?
DTO
struct message_source_t{
// Worker thread.
std::int32_t m_thread_id;
// Sender.
std::string m_subsystem;
};
struct message_t{
// Who sent a message.
message_source_t m_from;
// When the message was sent (unixtime).
std::tm m_when;
// Message text.
std::string m_text;
}; 3
О чем пойдет речь?
DTO
struct message_source_t{
// Worker thread.
std::int32_t m_thread_id;
// Sender.
std::string m_subsystem;
};
struct message_t{
// Who sent a message.
message_source_t m_from;
// When the message was sent (unixtime).
std::tm m_when;
// Message text.
std::string m_text;
};
JSON
“JSON (JavaScript Object Notation) is a
lightweight data-interchange format.”
http://www.json.org/
4
О чем пойдет речь?
DTO
struct message_source_t{
// Worker thread.
std::int32_t m_thread_id;
// Sender.
std::string m_subsystem;
};
struct message_t{
// Who sent a message.
message_source_t m_from;
// When the message was sent (unixtime).
std::tm m_when;
// Message text.
std::string m_text;
};
JSON
“JSON (JavaScript Object Notation) is a
lightweight data-interchange format.”
http://www.json.org/
{
"from" :
{
"thread_id" : 4242,
"sybsystem" : "json_dto"
},
"when" : "2016.09.28 19:55:00" ,
"text" : "Hello world!"
}
5
Это кому-нибудь нужно?
6
Это кому-нибудь нужно?
Да, похоже, что нужно:
● http://stackoverflow.com/questions/8220130/converting-c-class-to-json
● http://stackoverflow.com/questions/17549906/c-json-serialization
● http://stackoverflow.com/questions/35955137/convert-json-string-to-c-object-u
sing-casablanca-rest-sdk
7
Это кому-нибудь нужно?
8
Это кому-нибудь нужно?
I'd like to create a JSON string containing the instance variables of my class.
For example,
class Example {
std::string string;
std::map<std::string, std:string> map;
std::vector<int> vector;
};
would become:
{
"string":"the-string-value",
"map": {
"key1":"val1",
"key2":"val2"
},
"vector":[1,2,3,4]
}
9
Это кому-нибудь нужно?
“I want a way to serialize and deserialize Objects to JSON, as automatic as
possible.”
“Serialize: For me, the ideal way is that if I call in an instance JSONSerialize() it
returns an string with a JSON object that has all the public properties of the object
as "name_of_property": "value".”
“Deserialize: Just make an instance of the given object (let's say a dog) and call
JSONDeserialize(json_string), and that should fill all the public properties, creating
the needed objects in case that the properties are not primitives, or the needed
collections.”
10
Это кому-нибудь нужно?
“Is there any simple way to convert a json string in an object and back as shown in
this example? (http://www.newtonsoft.com/json/help/html/serializingjson.htm)”
11
Это кому-нибудь нужно?
В целом, хочется для заданной
структуры (класса) иметь
возможность конвертировать
инстанс в JSON и наоборот
получить инстанс из JSON.
При этом чтобы дополнительного
кода требовалось как можно
меньше.
12
Что такое json_dto?
13
Что такое json_dto?
● Нет, это не еще один JSON парсер
14
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
15
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
16
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
17
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
18
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
■ зависит только от RapidJSON (тоже header-only)
19
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
20
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
■ Механика описания правил позаимствована у Boost Serialization
21
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
■ Механика описания правил позаимствована у Boost Serialization
■ Для одного DTO требуется написать одну функцию
22
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
○ Интуитивно понятная поддержка типов
23
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
○ Интуитивно понятная поддержка типов
■ Простые типы: String, Number, Bool
24
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
○ Интуитивно понятная поддержка типов
■ Простые типы: String, Number, Bool
■ Массивы (Array)
25
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
○ Интуитивно понятная поддержка типов
■ Простые типы: String, Number, Bool
■ Массивы (Array)
■ Объекты (Object)
26
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
○ Интуитивно понятная поддержка типов
○ Поддержка null-полей
27
Что такое json_dto?
● Нет, это не еще один JSON парсер
○ В качестве парсера используется RapidJSON
Выбор был сделан на основе nativejson-benchmark
● Инструмент для отображения DTO в JSON и обратно по заданным
правилам
○ Header-only (C++14)
○ Требует немного дополнительного кода
○ Интуитивно понятная поддержка типов
○ Поддержка null-полей
○ Опциональные поля и значения по умолчанию
28
Давайте посмотрим,
что умеет json_dto
29
Hello world!
struct message_t
{
std::string m_from;
std::string m_text;
};
30
Hello world!
struct message_t
{
std::string m_from;
std::string m_text;
};
{
"from" : "<from>",
"text" : "<text>"
}
31
Hello world!
struct message_t
{
std::string m_from;
std::string m_text;
};
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
32
Hello world!
Чтение:
const std::string json_data{
R"({
"from" : "json_dto",
"text" : "Hello world!"
})" };
auto msg =
json_dto::from_json< message_t >(
json_data );
Запись:
auto json_str = json_dto::to_json( msg );
#include <json_dto/pub.hpp >
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
33
Hello world!
Чтение:
const std::string json_data{
R"({
"from" : "json_dto",
"text" : "Hello world!"
})" };
auto msg =
json_dto::from_json< message_t >(
json_data );
Запись:
auto json_str = json_dto::to_json( msg );
template <
typename TYPE,
unsigned RAPIDJSON_PARSEFLAGS =
rapidjson::kParseDefaultFlags >
TYPE
from_json( const std::string & json );
34
Hello world!
Чтение:
const std::string json_data{
R"({
"from" : "json_dto",
"text" : "Hello world!"
})" };
auto msg =
json_dto::from_json< message_t >(
json_data );
Запись:
auto json_str = json_dto::to_json( msg );
template < typename DTO >
std::string
to_json( const DTO & dto );
35
Какую роль играет json_io()
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
36
Какую роль играет json_io()
Это входная точка для json_dto. #include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
37
Какую роль играет json_io()
Это входная точка для json_dto, она служит
для описания:
● как читать DTO из JSON;
● как писать DTO в JSON.
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
38
Какую роль играет json_io()
Это входная точка для json_dto, она служит
для описания:
● как читать DTO из JSON;
● как писать DTO в JSON.
Шаблонной она является, для того чтобы
иметь всего одну логику для записи и чтения.
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
39
Какую роль играет json_io()
Это входная точка для json_dto, она служит
для описания:
● как читать DTO из JSON;
● как писать DTO в JSON.
Шаблонной она является, для того чтобы
иметь всего одну логику для записи и чтения.
json_dto подставляет в нее объекты двух
типов:
● json_dto::json_input_t
● json_dto::json_output_t
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
40
Внутри json_io()
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
41
Внутри json_io()
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
42
io & binder
Внутри json_io()
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
43
io & binder
json_input_t
json_ouput_t
Внутри json_io()
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
44
io & binder
json_input_t
json_ouput_t
Аналог
operator<<
operator>>
Внутри json_io()
#include <json_dto/pub.hpp>
// ...
struct message_t
{
std::string m_from;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text );
}
};
45
io & binder
json_input_t
json_ouput_t
Аналог
operator<<
operator>>
Привязка
Какие бывают привязки
46
Какие бывают привязки
● mandatory (обязательные)
template <
typename FIELD_TYPE,
typename VALIDATOR = empty_validator_t >
auto
mandatory(
string_ref_t field_name,
FIELD_TYPE & field,
VALIDATOR validator = VALIDATOR{} );
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional(
"text_format" ,
m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
m_is_private );
}
};
47
Какие бывают привязки
● optional (необязательные со
значением по умолчанию)
template <
typename FIELD_TYPE,
typename
FIELD_DEFAULT_VALUE_TYPE,
typename VALIDATOR = empty_validator_t >
auto
optional(
string_ref_t field_name,
FIELD_TYPE & field,
FIELD_DEFAULT_VALUE_TYPE
default_value,
VALIDATOR validator = VALIDATOR{} );
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional(
"text_format" ,
m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
m_is_private );
}
};
48
Какие бывают привязки
Пусть мы имеем:
auto msg =
json_dto::from_json<message_t>(json );
тогда:
1. {"from":"...","text":"..." }
msg.m_text_format == "text/plain"
2. {"from":"...","text":"...",
"text_format": "text/html" }
msg.m_text_format == "text/html"
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional(
"text_format" ,
m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
m_is_private );
}
};
49
Какие бывают привязки
● optional_no _default
(необязательные, без
значения по умолчанию)
template <
typename FIELD_TYPE,
typename VALIDATOR = empty_validator_t >
auto
optional_no_default(
string_ref_t field_name,
FIELD_TYPE & field,
VALIDATOR validator = VALIDATOR{} );
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional(
"text_format" ,
m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
m_is_private );
}
};
50
Почему отдельные имена
optional_no_default() и optional()
template <
typename FIELD_TYPE,
typename FIELD_DEFAULT_VALUE_TYPE,
typename VALIDATOR = empty_validator_t
>
auto
optional(
string_ref_t field_name,
FIELD_TYPE & field,
FIELD_DEFAULT_VALUE_TYPE default_value,
VALIDATOR validator = VALIDATOR{} );
template <
typename FIELD_TYPE,
typename VALIDATOR = empty_validator_t
>
auto
optional_no_default(
string_ref_t field_name,
FIELD_TYPE & field,
VALIDATOR validator = VALIDATOR{} );
51
Какие бывают привязки
● mandatory (обязательные)
● optional (необязательные со значением по умолчанию)
● optional_no _default (необязательные, без значения по умолчанию)
52
Поддерживаемые типы
53
Простые типы
C++
?
http://json.org/
JSON
54
Простые типы
C++
● Bool: bool;
http://json.org/
JSON
55
Простые типы
C++
● Bool: bool;
● Number:
std::int16_t,
std::uint16_t,
std::int32_t,
std::uint32_t,
std::int64_t,
std::uint64_t,
double;
http://json.org/
JSON
56
Простые типы
C++
● Bool: bool;
● Numeric:
std::int16_t,
std::uint16_t,
std::int32_t,
std::uint32_t,
std::int64_t,
std::uint64_t,
double;
● String: std::string
http://json.org/
JSON
57
“Сложные” типы
C++
В json_dto также поддерживаются:
● Массивы
● Вложенные DTO
http://json.org/
JSON
58
“Сложные” типы
C++
В json_dto также поддерживаются:
● Массивы
● Вложенные DTO
А также в состав json_dto входит
обертка для обработки null-значений
http://json.org/
JSON
59
Поддержка массивов
json_dto автоматически понимает, что значение поля должно быть массивом,
если в качестве второго аргумента для привязки указывается ссылка на
std::vector< ELEMENT_TYPE > &
Например:
struct str_array_t
{
std::vector< std::string > m_strings;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory( "strings", m_strings );
}
};
60
Поддержка массивов
Но есть два существенных ограничения:
61
Поддержка массивов
Но есть два существенных ограничения:
● При чтении массива все элементы должны быть одного типа
62
Поддержка массивов
Но есть два существенных ограничения:
● При чтении массива все элементы должны быть одного типа
● Значение по умолчанию для массивов в общем случае не работает
63
Поддержка вложенных DTO
Вложенные объекты поддерживаются
аналогично простым типам.
Достаточно чтобы тип был уже интегрирован
с json_dto.
64
Поддержка вложенных DTO
struct needle_t
{
std::string m_death{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory(
"death", m_death );
}
};
65
Поддержка вложенных DTO
struct egg_t
{
needle_t m_needle{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory(
"needle", m_needle );
}
};
struct needle_t
{
std::string m_death{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory(
"death", m_death );
}
};
66
Поддержка вложенных DTO
struct duck_t
{
egg_t m_egg{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory(
"egg", m_egg );
}
};
struct needle_t
{
std::string m_death{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory( "death", m_death );
}
};
struct egg_t
{
needle_t m_needle{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory( "needle",m_needle
);
}
}; 67
Поддержка вложенных DTO
struct duck_t
{
egg_t m_egg{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory(
"egg", m_egg );
}
};
struct needle_t
{
std::string m_death{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory( "death", m_death );
}
};
struct egg_t
{
needle_t m_needle{};
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io & json_dto::mandatory( "needle",m_needle
);
}
}; 68
Обработка null-значений
Для поддержки null значений в json_dto предусмотрен класс
json_dto::nullable_t<T>.
69
Обработка null-значений
Для поддержки null значений в json_dto предусмотрен класс
json_dto::nullable_t<T>.
Интерфейс json_dto::nullable_t<T> подражает std::optional
(C++17).
70
Обработка null-значений
Для поддержки null значений в json_dto предусмотрен класс
json_dto::nullable_t<T>.
Интерфейс json_dto::nullable_t<T> подражает std::optional
(C++17).
Требует явного объявления члена-данных с типом
json_dto::nullable_t<T>.
71
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
72
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
{
"from" : "json_dto",
"text" : "Hello CoreHard!",
"tags" :
[
"C++",
"JSON",
"CoreHard.by"
]
}
73
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
{
"from" : "json_dto",
"text" : "Hello world!",
"tags" :
[
"C++",
"JSON",
"CoreHard.by"
]
}
{
"from" : "json_dto",
"text" : "Hello world!",
"tags" : null
}
74
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
{
"from" : "json_dto",
"text" : "Hello world!",
"tags" :
[
"C++",
"JSON",
"CoreHard.by"
]
}
{
"from" : "json_dto",
"text" : "Hello world!",
"tags" : null
}
{
"from" : "json_dto",
"text" : "Hello world!"
} 75
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
auto msg =
json_dto::from_json< message_t >(
json_data );
// ...
if( msg.m_tags )
{
for( const auto & tag : *msg.m_tags )
{
do_smth( tag );
}
}
else
do_smth_else();
76
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
auto msg =
json_dto::from_json< message_t >(
json_data );
// ...
if( msg.m_tags )
{
for( const auto & tag : *msg.m_tags )
{
do_smth( tag );
}
}
else
do_smth_else();
nullable_t:: operator bool () const;
77
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
auto msg =
json_dto::from_json< message_t >(
json_data );
// ...
if( msg.m_tags )
{
for( const auto & tag : *msg.m_tags )
{
do_smth( tag );
}
}
else
do_smth_else();
const FIELD_TYPE &
nullable_t:: operator * () const; 78
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
message_t msg = create_msg( /* ... */ );
// ...
msg.m_tags.reset();
// ...
msg.m_tags =
std::vector< std::string >{ "1", "23" };
msg.m_tags->push_back( "42" );
void
nullable_t::reset(); 79
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
message_t msg = create_msg( /* ... */ );
// ...
msg.m_tags.reset();
// ...
msg.m_tags =
std::vector< std::string >{ "1", "23" };
msg.m_tags->push_back( "42" );
nullable_t &
nullable_t::operator= ( FIELD_TYPE && value ); 80
Обработка null-значений
struct message_t
{
std::string m_from;
std::string m_text;
json_dto::nullable_t<
std::vector< std::string > >
m_tags;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from
)
& json_dto::mandatory( "text", m_text
)
& json_dto::optional(
"tags", m_tags, nullptr );
}
};
message_t msg = create_msg( /* ... */ );
// ...
msg.m_tags.reset();
// ...
msg.m_tags =
std::vector< std::string >{ "1", "23" };
msg.m_tags->push_back( "42" );
FIELD_TYPE *
nullable_t:: operator-> (); 81
Что еще?
Есть возможность задать неинтрузивный json_io().
Еще есть валидаторы, которые можно задавать самому, но есть и немного
стандартных.
Можно определять способ чтения и записи кастомных типов.
82
Неинтрузивный json_io()
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
};
83
Неинтрузивный json_io()
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
};
84
namespace json_dto
{
template < typename JSON_IO >
void
json_io( JSON_IO & io, message_t & msg )
{
io
& json_dto::mandatory( "from", msg.m_from )
& json_dto::mandatory( "text", msg.m_text )
& json_dto::optional(
"text_format" ,
msg.m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
msg.m_is_private );
}
} /* namespace json_dto */
Неинтрузивный json_io()
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
};
85
namespace json_dto
{
template < typename JSON_IO >
void
json_io( JSON_IO & io, message_t & msg )
{
io
& json_dto::mandatory( "from", msg.m_from )
& json_dto::mandatory( "text", msg.m_text )
& json_dto::optional(
"text_format" ,
msg.m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
msg.m_is_private );
}
} /* namespace json_dto */
Неинтрузивный json_io()
struct message_t
{
std::string m_from{};
std::string m_text{};
std::string m_text_format{ "text/plain" };
bool m_is_private{ false };
};
86
namespace json_dto
{
template < typename JSON_IO >
void
json_io( JSON_IO & io, message_t & msg )
{
io
& json_dto::mandatory( "from", msg.m_from )
& json_dto::mandatory( "text", msg.m_text )
& json_dto::optional(
"text_format" ,
msg.m_text_format,
"text/plain" )
& json_dto::optional_no_default(
"is_private" ,
msg.m_is_private );
}
} /* namespace json_dto */
Поддержка кастомных типов
87
Поддержка кастомных типов
struct message_t
{
std::string m_from;
std::tm m_when;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "when", m_when )
& json_dto::mandatory( "text", m_text );
}
};
88
Поддержка кастомных типов
struct message_t
{
std::string m_from;
std::tm m_when;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "when", m_when )
& json_dto::mandatory( "text", m_text );
}
};
89
Поддержка кастомных типов
struct message_t
{
std::string m_from;
std::tm m_when;
std::string m_text;
template < typename JSON_IO >
void
json_io( JSON_IO & io )
{
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "when", m_when )
& json_dto::mandatory( "text", m_text );
}
};
namespace json_dto
{
template <>
void
read_json_value(
const rapidjson::Value & object,
std::tm & v )
{
// ...
}
template <>
void
write_json_value(
const std::tm & v,
rapidjson::Value & object,
rapidjson::MemoryPoolAllocator<> &allocator )
{
// ...
}
} /* namespace json_dto */
90
Валидаторы
Функциональный объект (function object), который получает один параметр.
Если значение корректно, то валидатор просто штатно завершает свою
работу.
Если значение некорректное, то валидатор должен выбросить исключение.
91
Валидаторы
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional( "log_level", m_log_level, nullptr );
92
Валидаторы
io
& json_dto::mandatory( "from", m_from )
& json_dto::mandatory( "text", m_text )
& json_dto::optional( "log_level", m_log_level, nullptr );
io
& json_dto::mandatory(
"from", m_from,
[]( const auto & from ){
if( from.empty() ) throw std::runtime_error{ "from cannot be empty" };
} )
& json_dto::mandatory( "text", m_text, check_all_7bit )
& json_dto::optional(
"log_level", m_log_level,nullptr,
json_dto::one_of_constraint(
{ std::string{ "trace" }, std::string{ "info" },std::string{ "error" } } ) );
93
Спасибо!
Николай Гродзицкий
ngrodzitski@gmail.com
https://bitbucket.org/sobjectizerteam/json_dto-0.1
https://github.com/miloyip/rapidjson
http://www.boost.org/doc/libs/1_62_0/libs/serialization/doc/index.html
http://en.cppreference.com/w/cpp/utility/optional
Альтернативы: https://github.com/Loki-Astari/ThorsSerializer.git
94

More Related Content

What's hot

C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and catscorehard_by
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...
DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...
DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...it-people
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеPython Meetup
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage CollectorOlexandra Dmytrenko
 

What's hot (7)

C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...
DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...
DUMP-2015: «Полнотекстовый поиск по почте Mail.Ru» Дмитрий Калугин-Балашов, M...
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage Collector
 
Bytecode
BytecodeBytecode
Bytecode
 

Viewers also liked

A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodeA Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodePVS-Studio
 
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
 
Теория и практика написания безопасного кода на C++
Теория и практика написания безопасного кода на C++Теория и практика написания безопасного кода на C++
Теория и практика написания безопасного кода на C++corehard_by
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtSergey Platonov
 
Хитрости мультипоточности
Хитрости мультипоточностиХитрости мультипоточности
Хитрости мультипоточностиcorehard_by
 
Разработка и тестирование интернета вещей. Тренды индустрии
Разработка и тестирование интернета вещей. Тренды индустрииРазработка и тестирование интернета вещей. Тренды индустрии
Разработка и тестирование интернета вещей. Тренды индустрииcorehard_by
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
о некоторых вопросах бинарной совместимости в C++
о некоторых вопросах бинарной совместимости в C++о некоторых вопросах бинарной совместимости в C++
о некоторых вопросах бинарной совместимости в C++corehard_by
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IPlatonov Sergey
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17Sergey Platonov
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3Platonov Sergey
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines Sergey Zubkov
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projectscorehard_by
 

Viewers also liked (15)

A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodeA Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
 
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
 
Теория и практика написания безопасного кода на C++
Теория и практика написания безопасного кода на C++Теория и практика написания безопасного кода на C++
Теория и практика написания безопасного кода на C++
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
 
Хитрости мультипоточности
Хитрости мультипоточностиХитрости мультипоточности
Хитрости мультипоточности
 
Разработка и тестирование интернета вещей. Тренды индустрии
Разработка и тестирование интернета вещей. Тренды индустрииРазработка и тестирование интернета вещей. Тренды индустрии
Разработка и тестирование интернета вещей. Тренды индустрии
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
о некоторых вопросах бинарной совместимости в C++
о некоторых вопросах бинарной совместимости в C++о некоторых вопросах бинарной совместимости в C++
о некоторых вопросах бинарной совместимости в C++
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
 

Similar to упрощаем переход от Json к c++ структурам и обратно (николай гродзицкий)

Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupMail.ru Group
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)Ontico
 
MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?Alexey Tokar
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковSergey Platonov
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API: SyntaxTree vs CodeDom, SemanticModel vs ReflectionRoslyn API: SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs ReflectionDenis Tsvettsih
 
Большой брат помогает тебе
Большой брат помогает тебеБольшой брат помогает тебе
Большой брат помогает тебеTatyanazaxarova
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Yandex
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETGoSharp
 
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...Ontico
 
Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...Volodymyr Hotsyk
 
Web performance 101 [GDG nsk webdev meetup #3]
Web performance 101 [GDG nsk webdev meetup #3]Web performance 101 [GDG nsk webdev meetup #3]
Web performance 101 [GDG nsk webdev meetup #3]Eugene Chekan
 
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Yandex
 

Similar to упрощаем переход от Json к c++ структурам и обратно (николай гродзицкий) (20)

Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
 
MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кодаSECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API: SyntaxTree vs CodeDom, SemanticModel vs ReflectionRoslyn API: SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
 
Большой брат помогает тебе
Большой брат помогает тебеБольшой брат помогает тебе
Большой брат помогает тебе
 
лекция 4
лекция 4лекция 4
лекция 4
 
лекция 4
лекция 4лекция 4
лекция 4
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
 
Net 3.0 & Linq
Net 3.0 & LinqNet 3.0 & Linq
Net 3.0 & Linq
 
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
 
Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...
 
Web performance 101 [GDG nsk webdev meetup #3]
Web performance 101 [GDG nsk webdev meetup #3]Web performance 101 [GDG nsk webdev meetup #3]
Web performance 101 [GDG nsk webdev meetup #3]
 
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 

упрощаем переход от Json к c++ структурам и обратно (николай гродзицкий)

  • 1. Упрощаем переход от JSON к C++ структурам и обратно Николай Гродзицкий
  • 3. О чем пойдет речь? DTO struct message_source_t{ // Worker thread. std::int32_t m_thread_id; // Sender. std::string m_subsystem; }; struct message_t{ // Who sent a message. message_source_t m_from; // When the message was sent (unixtime). std::tm m_when; // Message text. std::string m_text; }; 3
  • 4. О чем пойдет речь? DTO struct message_source_t{ // Worker thread. std::int32_t m_thread_id; // Sender. std::string m_subsystem; }; struct message_t{ // Who sent a message. message_source_t m_from; // When the message was sent (unixtime). std::tm m_when; // Message text. std::string m_text; }; JSON “JSON (JavaScript Object Notation) is a lightweight data-interchange format.” http://www.json.org/ 4
  • 5. О чем пойдет речь? DTO struct message_source_t{ // Worker thread. std::int32_t m_thread_id; // Sender. std::string m_subsystem; }; struct message_t{ // Who sent a message. message_source_t m_from; // When the message was sent (unixtime). std::tm m_when; // Message text. std::string m_text; }; JSON “JSON (JavaScript Object Notation) is a lightweight data-interchange format.” http://www.json.org/ { "from" : { "thread_id" : 4242, "sybsystem" : "json_dto" }, "when" : "2016.09.28 19:55:00" , "text" : "Hello world!" } 5
  • 7. Это кому-нибудь нужно? Да, похоже, что нужно: ● http://stackoverflow.com/questions/8220130/converting-c-class-to-json ● http://stackoverflow.com/questions/17549906/c-json-serialization ● http://stackoverflow.com/questions/35955137/convert-json-string-to-c-object-u sing-casablanca-rest-sdk 7
  • 9. Это кому-нибудь нужно? I'd like to create a JSON string containing the instance variables of my class. For example, class Example { std::string string; std::map<std::string, std:string> map; std::vector<int> vector; }; would become: { "string":"the-string-value", "map": { "key1":"val1", "key2":"val2" }, "vector":[1,2,3,4] } 9
  • 10. Это кому-нибудь нужно? “I want a way to serialize and deserialize Objects to JSON, as automatic as possible.” “Serialize: For me, the ideal way is that if I call in an instance JSONSerialize() it returns an string with a JSON object that has all the public properties of the object as "name_of_property": "value".” “Deserialize: Just make an instance of the given object (let's say a dog) and call JSONDeserialize(json_string), and that should fill all the public properties, creating the needed objects in case that the properties are not primitives, or the needed collections.” 10
  • 11. Это кому-нибудь нужно? “Is there any simple way to convert a json string in an object and back as shown in this example? (http://www.newtonsoft.com/json/help/html/serializingjson.htm)” 11
  • 12. Это кому-нибудь нужно? В целом, хочется для заданной структуры (класса) иметь возможность конвертировать инстанс в JSON и наоборот получить инстанс из JSON. При этом чтобы дополнительного кода требовалось как можно меньше. 12
  • 14. Что такое json_dto? ● Нет, это не еще один JSON парсер 14
  • 15. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON 15
  • 16. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark 16
  • 17. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам 17
  • 18. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) 18
  • 19. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ■ зависит только от RapidJSON (тоже header-only) 19
  • 20. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода 20
  • 21. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ■ Механика описания правил позаимствована у Boost Serialization 21
  • 22. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ■ Механика описания правил позаимствована у Boost Serialization ■ Для одного DTO требуется написать одну функцию 22
  • 23. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ○ Интуитивно понятная поддержка типов 23
  • 24. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ○ Интуитивно понятная поддержка типов ■ Простые типы: String, Number, Bool 24
  • 25. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ○ Интуитивно понятная поддержка типов ■ Простые типы: String, Number, Bool ■ Массивы (Array) 25
  • 26. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ○ Интуитивно понятная поддержка типов ■ Простые типы: String, Number, Bool ■ Массивы (Array) ■ Объекты (Object) 26
  • 27. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ○ Интуитивно понятная поддержка типов ○ Поддержка null-полей 27
  • 28. Что такое json_dto? ● Нет, это не еще один JSON парсер ○ В качестве парсера используется RapidJSON Выбор был сделан на основе nativejson-benchmark ● Инструмент для отображения DTO в JSON и обратно по заданным правилам ○ Header-only (C++14) ○ Требует немного дополнительного кода ○ Интуитивно понятная поддержка типов ○ Поддержка null-полей ○ Опциональные поля и значения по умолчанию 28
  • 30. Hello world! struct message_t { std::string m_from; std::string m_text; }; 30
  • 31. Hello world! struct message_t { std::string m_from; std::string m_text; }; { "from" : "<from>", "text" : "<text>" } 31
  • 32. Hello world! struct message_t { std::string m_from; std::string m_text; }; #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 32
  • 33. Hello world! Чтение: const std::string json_data{ R"({ "from" : "json_dto", "text" : "Hello world!" })" }; auto msg = json_dto::from_json< message_t >( json_data ); Запись: auto json_str = json_dto::to_json( msg ); #include <json_dto/pub.hpp > // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 33
  • 34. Hello world! Чтение: const std::string json_data{ R"({ "from" : "json_dto", "text" : "Hello world!" })" }; auto msg = json_dto::from_json< message_t >( json_data ); Запись: auto json_str = json_dto::to_json( msg ); template < typename TYPE, unsigned RAPIDJSON_PARSEFLAGS = rapidjson::kParseDefaultFlags > TYPE from_json( const std::string & json ); 34
  • 35. Hello world! Чтение: const std::string json_data{ R"({ "from" : "json_dto", "text" : "Hello world!" })" }; auto msg = json_dto::from_json< message_t >( json_data ); Запись: auto json_str = json_dto::to_json( msg ); template < typename DTO > std::string to_json( const DTO & dto ); 35
  • 36. Какую роль играет json_io() #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 36
  • 37. Какую роль играет json_io() Это входная точка для json_dto. #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 37
  • 38. Какую роль играет json_io() Это входная точка для json_dto, она служит для описания: ● как читать DTO из JSON; ● как писать DTO в JSON. #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 38
  • 39. Какую роль играет json_io() Это входная точка для json_dto, она служит для описания: ● как читать DTO из JSON; ● как писать DTO в JSON. Шаблонной она является, для того чтобы иметь всего одну логику для записи и чтения. #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 39
  • 40. Какую роль играет json_io() Это входная точка для json_dto, она служит для описания: ● как читать DTO из JSON; ● как писать DTO в JSON. Шаблонной она является, для того чтобы иметь всего одну логику для записи и чтения. json_dto подставляет в нее объекты двух типов: ● json_dto::json_input_t ● json_dto::json_output_t #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 40
  • 41. Внутри json_io() #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 41
  • 42. Внутри json_io() #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 42 io & binder
  • 43. Внутри json_io() #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 43 io & binder json_input_t json_ouput_t
  • 44. Внутри json_io() #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 44 io & binder json_input_t json_ouput_t Аналог operator<< operator>>
  • 45. Внутри json_io() #include <json_dto/pub.hpp> // ... struct message_t { std::string m_from; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ); } }; 45 io & binder json_input_t json_ouput_t Аналог operator<< operator>> Привязка
  • 47. Какие бывают привязки ● mandatory (обязательные) template < typename FIELD_TYPE, typename VALIDATOR = empty_validator_t > auto mandatory( string_ref_t field_name, FIELD_TYPE & field, VALIDATOR validator = VALIDATOR{} ); struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "text_format" , m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , m_is_private ); } }; 47
  • 48. Какие бывают привязки ● optional (необязательные со значением по умолчанию) template < typename FIELD_TYPE, typename FIELD_DEFAULT_VALUE_TYPE, typename VALIDATOR = empty_validator_t > auto optional( string_ref_t field_name, FIELD_TYPE & field, FIELD_DEFAULT_VALUE_TYPE default_value, VALIDATOR validator = VALIDATOR{} ); struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "text_format" , m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , m_is_private ); } }; 48
  • 49. Какие бывают привязки Пусть мы имеем: auto msg = json_dto::from_json<message_t>(json ); тогда: 1. {"from":"...","text":"..." } msg.m_text_format == "text/plain" 2. {"from":"...","text":"...", "text_format": "text/html" } msg.m_text_format == "text/html" struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "text_format" , m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , m_is_private ); } }; 49
  • 50. Какие бывают привязки ● optional_no _default (необязательные, без значения по умолчанию) template < typename FIELD_TYPE, typename VALIDATOR = empty_validator_t > auto optional_no_default( string_ref_t field_name, FIELD_TYPE & field, VALIDATOR validator = VALIDATOR{} ); struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "text_format" , m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , m_is_private ); } }; 50
  • 51. Почему отдельные имена optional_no_default() и optional() template < typename FIELD_TYPE, typename FIELD_DEFAULT_VALUE_TYPE, typename VALIDATOR = empty_validator_t > auto optional( string_ref_t field_name, FIELD_TYPE & field, FIELD_DEFAULT_VALUE_TYPE default_value, VALIDATOR validator = VALIDATOR{} ); template < typename FIELD_TYPE, typename VALIDATOR = empty_validator_t > auto optional_no_default( string_ref_t field_name, FIELD_TYPE & field, VALIDATOR validator = VALIDATOR{} ); 51
  • 52. Какие бывают привязки ● mandatory (обязательные) ● optional (необязательные со значением по умолчанию) ● optional_no _default (необязательные, без значения по умолчанию) 52
  • 55. Простые типы C++ ● Bool: bool; http://json.org/ JSON 55
  • 56. Простые типы C++ ● Bool: bool; ● Number: std::int16_t, std::uint16_t, std::int32_t, std::uint32_t, std::int64_t, std::uint64_t, double; http://json.org/ JSON 56
  • 57. Простые типы C++ ● Bool: bool; ● Numeric: std::int16_t, std::uint16_t, std::int32_t, std::uint32_t, std::int64_t, std::uint64_t, double; ● String: std::string http://json.org/ JSON 57
  • 58. “Сложные” типы C++ В json_dto также поддерживаются: ● Массивы ● Вложенные DTO http://json.org/ JSON 58
  • 59. “Сложные” типы C++ В json_dto также поддерживаются: ● Массивы ● Вложенные DTO А также в состав json_dto входит обертка для обработки null-значений http://json.org/ JSON 59
  • 60. Поддержка массивов json_dto автоматически понимает, что значение поля должно быть массивом, если в качестве второго аргумента для привязки указывается ссылка на std::vector< ELEMENT_TYPE > & Например: struct str_array_t { std::vector< std::string > m_strings; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "strings", m_strings ); } }; 60
  • 61. Поддержка массивов Но есть два существенных ограничения: 61
  • 62. Поддержка массивов Но есть два существенных ограничения: ● При чтении массива все элементы должны быть одного типа 62
  • 63. Поддержка массивов Но есть два существенных ограничения: ● При чтении массива все элементы должны быть одного типа ● Значение по умолчанию для массивов в общем случае не работает 63
  • 64. Поддержка вложенных DTO Вложенные объекты поддерживаются аналогично простым типам. Достаточно чтобы тип был уже интегрирован с json_dto. 64
  • 65. Поддержка вложенных DTO struct needle_t { std::string m_death{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "death", m_death ); } }; 65
  • 66. Поддержка вложенных DTO struct egg_t { needle_t m_needle{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "needle", m_needle ); } }; struct needle_t { std::string m_death{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "death", m_death ); } }; 66
  • 67. Поддержка вложенных DTO struct duck_t { egg_t m_egg{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "egg", m_egg ); } }; struct needle_t { std::string m_death{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "death", m_death ); } }; struct egg_t { needle_t m_needle{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "needle",m_needle ); } }; 67
  • 68. Поддержка вложенных DTO struct duck_t { egg_t m_egg{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "egg", m_egg ); } }; struct needle_t { std::string m_death{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "death", m_death ); } }; struct egg_t { needle_t m_needle{}; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "needle",m_needle ); } }; 68
  • 69. Обработка null-значений Для поддержки null значений в json_dto предусмотрен класс json_dto::nullable_t<T>. 69
  • 70. Обработка null-значений Для поддержки null значений в json_dto предусмотрен класс json_dto::nullable_t<T>. Интерфейс json_dto::nullable_t<T> подражает std::optional (C++17). 70
  • 71. Обработка null-значений Для поддержки null значений в json_dto предусмотрен класс json_dto::nullable_t<T>. Интерфейс json_dto::nullable_t<T> подражает std::optional (C++17). Требует явного объявления члена-данных с типом json_dto::nullable_t<T>. 71
  • 72. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; 72
  • 73. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; { "from" : "json_dto", "text" : "Hello CoreHard!", "tags" : [ "C++", "JSON", "CoreHard.by" ] } 73
  • 74. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; { "from" : "json_dto", "text" : "Hello world!", "tags" : [ "C++", "JSON", "CoreHard.by" ] } { "from" : "json_dto", "text" : "Hello world!", "tags" : null } 74
  • 75. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; { "from" : "json_dto", "text" : "Hello world!", "tags" : [ "C++", "JSON", "CoreHard.by" ] } { "from" : "json_dto", "text" : "Hello world!", "tags" : null } { "from" : "json_dto", "text" : "Hello world!" } 75
  • 76. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; auto msg = json_dto::from_json< message_t >( json_data ); // ... if( msg.m_tags ) { for( const auto & tag : *msg.m_tags ) { do_smth( tag ); } } else do_smth_else(); 76
  • 77. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; auto msg = json_dto::from_json< message_t >( json_data ); // ... if( msg.m_tags ) { for( const auto & tag : *msg.m_tags ) { do_smth( tag ); } } else do_smth_else(); nullable_t:: operator bool () const; 77
  • 78. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; auto msg = json_dto::from_json< message_t >( json_data ); // ... if( msg.m_tags ) { for( const auto & tag : *msg.m_tags ) { do_smth( tag ); } } else do_smth_else(); const FIELD_TYPE & nullable_t:: operator * () const; 78
  • 79. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; message_t msg = create_msg( /* ... */ ); // ... msg.m_tags.reset(); // ... msg.m_tags = std::vector< std::string >{ "1", "23" }; msg.m_tags->push_back( "42" ); void nullable_t::reset(); 79
  • 80. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; message_t msg = create_msg( /* ... */ ); // ... msg.m_tags.reset(); // ... msg.m_tags = std::vector< std::string >{ "1", "23" }; msg.m_tags->push_back( "42" ); nullable_t & nullable_t::operator= ( FIELD_TYPE && value ); 80
  • 81. Обработка null-значений struct message_t { std::string m_from; std::string m_text; json_dto::nullable_t< std::vector< std::string > > m_tags; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "tags", m_tags, nullptr ); } }; message_t msg = create_msg( /* ... */ ); // ... msg.m_tags.reset(); // ... msg.m_tags = std::vector< std::string >{ "1", "23" }; msg.m_tags->push_back( "42" ); FIELD_TYPE * nullable_t:: operator-> (); 81
  • 82. Что еще? Есть возможность задать неинтрузивный json_io(). Еще есть валидаторы, которые можно задавать самому, но есть и немного стандартных. Можно определять способ чтения и записи кастомных типов. 82
  • 83. Неинтрузивный json_io() struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; }; 83
  • 84. Неинтрузивный json_io() struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; }; 84 namespace json_dto { template < typename JSON_IO > void json_io( JSON_IO & io, message_t & msg ) { io & json_dto::mandatory( "from", msg.m_from ) & json_dto::mandatory( "text", msg.m_text ) & json_dto::optional( "text_format" , msg.m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , msg.m_is_private ); } } /* namespace json_dto */
  • 85. Неинтрузивный json_io() struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; }; 85 namespace json_dto { template < typename JSON_IO > void json_io( JSON_IO & io, message_t & msg ) { io & json_dto::mandatory( "from", msg.m_from ) & json_dto::mandatory( "text", msg.m_text ) & json_dto::optional( "text_format" , msg.m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , msg.m_is_private ); } } /* namespace json_dto */
  • 86. Неинтрузивный json_io() struct message_t { std::string m_from{}; std::string m_text{}; std::string m_text_format{ "text/plain" }; bool m_is_private{ false }; }; 86 namespace json_dto { template < typename JSON_IO > void json_io( JSON_IO & io, message_t & msg ) { io & json_dto::mandatory( "from", msg.m_from ) & json_dto::mandatory( "text", msg.m_text ) & json_dto::optional( "text_format" , msg.m_text_format, "text/plain" ) & json_dto::optional_no_default( "is_private" , msg.m_is_private ); } } /* namespace json_dto */
  • 88. Поддержка кастомных типов struct message_t { std::string m_from; std::tm m_when; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "when", m_when ) & json_dto::mandatory( "text", m_text ); } }; 88
  • 89. Поддержка кастомных типов struct message_t { std::string m_from; std::tm m_when; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "when", m_when ) & json_dto::mandatory( "text", m_text ); } }; 89
  • 90. Поддержка кастомных типов struct message_t { std::string m_from; std::tm m_when; std::string m_text; template < typename JSON_IO > void json_io( JSON_IO & io ) { io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "when", m_when ) & json_dto::mandatory( "text", m_text ); } }; namespace json_dto { template <> void read_json_value( const rapidjson::Value & object, std::tm & v ) { // ... } template <> void write_json_value( const std::tm & v, rapidjson::Value & object, rapidjson::MemoryPoolAllocator<> &allocator ) { // ... } } /* namespace json_dto */ 90
  • 91. Валидаторы Функциональный объект (function object), который получает один параметр. Если значение корректно, то валидатор просто штатно завершает свою работу. Если значение некорректное, то валидатор должен выбросить исключение. 91
  • 92. Валидаторы io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "log_level", m_log_level, nullptr ); 92
  • 93. Валидаторы io & json_dto::mandatory( "from", m_from ) & json_dto::mandatory( "text", m_text ) & json_dto::optional( "log_level", m_log_level, nullptr ); io & json_dto::mandatory( "from", m_from, []( const auto & from ){ if( from.empty() ) throw std::runtime_error{ "from cannot be empty" }; } ) & json_dto::mandatory( "text", m_text, check_all_7bit ) & json_dto::optional( "log_level", m_log_level,nullptr, json_dto::one_of_constraint( { std::string{ "trace" }, std::string{ "info" },std::string{ "error" } } ) ); 93