forked from mail-ru-im/im-desktop
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathjson_unserialize_helpers.h
137 lines (113 loc) · 4.34 KB
/
json_unserialize_helpers.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#pragma once
#include <rapidjson/document.h>
#include <rapidjson/schema.h>
#include <string>
#include <string_view>
namespace common::json
{
template <typename T>
inline std::string rapidjson_get_string(const T& value) { return std::string(value.GetString(), value.GetStringLength()); }
template <>
inline std::string rapidjson_get_string<rapidjson::StringBuffer>(const rapidjson::StringBuffer& value) { return std::string(value.GetString(), value.GetSize()); }
template <typename T>
inline std::string_view rapidjson_get_string_view(const T& value) { return std::string_view(value.GetString(), value.GetStringLength()); }
template <>
inline std::string_view rapidjson_get_string_view<rapidjson::StringBuffer>(const rapidjson::StringBuffer& value) { return std::string_view(value.GetString(), value.GetSize()); }
}
namespace common::json
{
inline auto make_string_ref(std::string_view str)
{
return rapidjson::StringRef(str.data(), str.size());
};
inline namespace v2
{
template <class T>
auto get_value(const rapidjson::Value& _node, std::string_view _name) -> std::optional<T> = delete;
}
template <>
inline std::optional<std::string> get_value<std::string>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsString())
return rapidjson_get_string(iter->value);
}
return {};
}
template <>
inline std::optional<std::string_view> get_value<std::string_view>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsString())
return rapidjson_get_string_view(iter->value);
}
return {};
}
template <>
inline std::optional<int> get_value<int>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsInt())
return iter->value.GetInt();
}
return {};
}
template <>
inline std::optional<unsigned int> get_value<unsigned int>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsUint())
return iter->value.GetUint();
}
return {};
}
template <>
inline std::optional<int64_t> get_value<int64_t>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsInt64())
return iter->value.GetInt64();
}
return {};
}
template <>
inline std::optional<uint64_t> get_value<uint64_t>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsUint64())
return iter->value.GetUint64();
}
return {};
}
template <>
inline std::optional<double> get_value<double>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd() && iter->value.IsDouble())
return iter->value.GetDouble();
}
return {};
}
template <>
inline std::optional<bool> get_value<bool>(const rapidjson::Value& _node, std::string_view _name)
{
if (_node.IsObject())
{
if (const auto iter = _node.FindMember(make_string_ref(_name)); iter != _node.MemberEnd())
{
if (iter->value.IsBool())
return iter->value.GetBool();
else if (iter->value.IsInt() || iter->value.IsUint())
return iter->value != 0;
}
}
return {};
}
}