comparison cpp/json_util/json_util.cpp @ 650:ff73f2dd1c82

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