annotate cpp/json_util/json_util.cpp @ 665:4a59972e5eb8

options: remove useless main
author David Demelier <markand@malikania.fr>
date Thu, 19 Sep 2019 11:34:32 +0000
parents 734ce3a26a58
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
650
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * json_util.cpp -- utilities for JSON
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
653
87e1f4c7da76 misc: happy new year!
David Demelier <markand@malikania.fr>
parents: 650
diff changeset
4 * Copyright (c) 2019 David Demelier <markand@malikania.fr>
650
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <limits>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <type_traits>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
21
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include "json_util.hpp"
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
23
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 using nlohmann::json;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
25
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 namespace json_util {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
27
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 namespace {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
29
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 template <typename Int>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 auto clampi(const json& value) noexcept -> std::optional<Int>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 static_assert(std::is_signed<Int>::value, "Int must be signed");
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
34
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 if (!value.is_number_integer())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
37
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 const auto ret = value.get<std::int64_t>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
39
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 if (ret < std::numeric_limits<Int>::min() || ret > std::numeric_limits<Int>::max())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
42
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 return static_cast<Int>(ret);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
45
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 template <typename Int>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 auto clampu(const json& value) noexcept -> std::optional<Int>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 static_assert(std::is_unsigned<Int>::value, "Int must be unsigned");
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
50
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 if (!value.is_number_unsigned())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
53
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 const auto ret = value.get<std::uint64_t>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 if (ret > std::numeric_limits<Int>::max())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 return static_cast<Int>(ret);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 } // !namespace
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
63
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 auto type_traits<bool>::get(const json& value) noexcept -> std::optional<bool>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 if (!value.is_boolean())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 return value.get<bool>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
71
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 auto type_traits<double>::get(const json& value) noexcept -> std::optional<double>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 if (!value.is_number_float())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
76
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 return value.get<double>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
79
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 auto type_traits<std::string>::get(const json& value) -> std::optional<std::string>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 if (!value.is_string())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
84
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 return value.get<std::string>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
87
656
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
88 auto type_traits<std::string_view>::get(const json& value) -> std::optional<std::string_view>
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
89 {
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
90 if (!value.is_string())
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
91 return std::nullopt;
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
92
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
93 return value.get<std::string_view>();
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
94 }
734ce3a26a58 json_util: upgrade to 3.5.0 and add string_view overload
David Demelier <markand@malikania.fr>
parents: 653
diff changeset
95
650
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 auto type_traits<std::int8_t>::get(const json& value) -> std::optional<std::int8_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 return clampi<std::int8_t>(value);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
100
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 auto type_traits<std::int16_t>::get(const json& value) -> std::optional<std::int16_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 return clampi<std::int16_t>(value);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 auto type_traits<std::int32_t>::get(const json& value) -> std::optional<std::int32_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 return clampi<std::int32_t>(value);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
110
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 auto type_traits<std::int64_t>::get(const json& value) noexcept -> std::optional<std::int64_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 if (!value.is_number_integer())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
115
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 return value.get<std::int64_t>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
118
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 auto type_traits<std::uint8_t>::get(const json& value) -> std::optional<std::uint8_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 return clampu<std::uint8_t>(value);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 auto type_traits<std::uint16_t>::get(const json& value) -> std::optional<std::uint16_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 return clampu<std::uint16_t>(value);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 auto type_traits<std::uint32_t>::get(const json& value) -> std::optional<std::uint32_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 return clampu<std::uint32_t>(value);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
133
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 auto type_traits<std::uint64_t>::get(const json& value) noexcept -> std::optional<std::uint64_t>
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 if (!value.is_number_unsigned())
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 return std::nullopt;
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
138
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 return value.get<std::uint64_t>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
141
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 auto pretty(const json& value, int indent) -> std::string
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 switch (value.type()) {
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 case json::value_t::null:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 return "null";
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 case json::value_t::string:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 return value.get<std::string>();
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 case json::value_t::boolean:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 return value.get<bool>() ? "true" : "false";
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 case json::value_t::number_integer:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 return std::to_string(value.get<std::int64_t>());
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 case json::value_t::number_unsigned:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 return std::to_string(value.get<std::uint64_t>());
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 case json::value_t::number_float:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 return std::to_string(value.get<double>());
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 default:
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 return value.dump(indent);
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 }
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
161
ff73f2dd1c82 json_util: split and style
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 } // !json_util