• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 18222111010

03 Oct 2025 08:13AM UTC coverage: 99.37% (-0.001%) from 99.371%
18222111010

push

github

bblanchon
Extract `VariantImpl`

409 of 410 new or added lines in 28 files covered. (99.76%)

3 existing lines in 2 files now uncovered.

3945 of 3970 relevant lines covered (99.37%)

10359.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.04
/src/ArduinoJson/Variant/ConverterImpl.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2025, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <ArduinoJson/Json/JsonSerializer.hpp>
8
#include <ArduinoJson/Memory/StringBuilder.hpp>
9
#include <ArduinoJson/Polyfills/utility.hpp>
10
#include <ArduinoJson/Variant/JsonVariantConst.hpp>
11

12
#if ARDUINOJSON_ENABLE_STD_STRING
13
#  include <string>
14
#endif
15

16
#if ARDUINOJSON_ENABLE_STRING_VIEW
17
#  include <string_view>
18
#endif
19

20
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
21

22
template <typename T, typename Enable>
23
struct Converter {
24
  static_assert(!detail::is_same<T, char>::value,
25
                "type 'char' is not supported, use 'signed char', 'unsigned "
26
                "char' or another integer type instead");
27

28
  static void toJson(const T& src, JsonVariant dst) {
520✔
29
    // clang-format off
30
    convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
520✔
31
    // clang-format on
32
  }
520✔
33

34
  static detail::decay_t<T> fromJson(JsonVariantConst src) {
471✔
35
    static_assert(!detail::is_same<T, char*>::value,
36
                  "type 'char*' is not supported, use 'const char*' instead");
37

38
    // clang-format off
39
    T result; // Error here? See https://arduinojson.org/v7/non-default-constructible/
470✔
40
    convertFromJson(src, result);  // Error here? See https://arduinojson.org/v7/unsupported-as/
471✔
41
    // clang-format on
42
    return result;
471✔
43
  }
×
44

45
  static bool checkJson(JsonVariantConst src) {
25✔
46
    static_assert(!detail::is_same<T, char*>::value,
47
                  "type 'char*' is not supported, use 'const char*' instead");
48

49
    T dummy = T();
25✔
50
    // clang-format off
51
    return canConvertFromJson(src, dummy);  // Error here? See https://arduinojson.org/v7/unsupported-is/
50✔
52
    // clang-format on
53
  }
21✔
54
};
55

56
template <typename T>
57
struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
58
                                        !detail::is_same<bool, T>::value &&
59
                                        !detail::is_same<char, T>::value>>
60
    : private detail::VariantAttorney {
61
  static bool toJson(T src, JsonVariant dst) {
1,433✔
62
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
63
    return getVariantImpl(dst).setInteger(src);
1,433✔
64
  }
65

66
  static T fromJson(JsonVariantConst src) {
202✔
67
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
68
    return getVariantImpl(src).template asIntegral<T>();
202✔
69
  }
70

71
  static bool checkJson(JsonVariantConst src) {
149✔
72
    return getVariantImpl(src).template isInteger<T>();
149✔
73
  }
74
};
75

76
template <typename T>
77
struct Converter<T, detail::enable_if_t<detail::is_enum<T>::value>>
78
    : private detail::VariantAttorney {
79
  static bool toJson(T src, JsonVariant dst) {
1✔
80
    return dst.set(static_cast<JsonInteger>(src));
1✔
81
  }
82

83
  static T fromJson(JsonVariantConst src) {
1✔
84
    return static_cast<T>(getVariantImpl(src).template asIntegral<int>());
1✔
85
  }
86

87
  static bool checkJson(JsonVariantConst src) {
18✔
88
    return getVariantImpl(src).template isInteger<int>();
18✔
89
  }
90
};
91

92
template <>
93
struct Converter<bool> : private detail::VariantAttorney {
94
  static bool toJson(bool src, JsonVariant dst) {
250✔
95
    return getVariantImpl(dst).setBoolean(src);
250✔
96
  }
97

98
  static bool fromJson(JsonVariantConst src) {
1,254✔
99
    return getVariantImpl(src).asBoolean();
1,254✔
100
  }
101

102
  static bool checkJson(JsonVariantConst src) {
38✔
103
    auto data = getData(src);
38✔
104
    return data && data->isBoolean();
38✔
105
  }
106
};
107

108
template <typename T>
109
struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
110
    : private detail::VariantAttorney {
111
  static bool toJson(T src, JsonVariant dst) {
73✔
112
    return getVariantImpl(dst).setFloat(src);
73✔
113
  }
114

115
  static T fromJson(JsonVariantConst src) {
55✔
116
    return getVariantImpl(src).template asFloat<T>();
55✔
117
  }
118

119
  static bool checkJson(JsonVariantConst src) {
48✔
120
    auto data = getData(src);
48✔
121
    return data && data->isFloat();
48✔
122
  }
123
};
124

125
template <>
126
struct Converter<const char*> : private detail::VariantAttorney {
127
  static void toJson(const char* src, JsonVariant dst) {
65,582✔
128
    getVariantImpl(dst).setString(detail::adaptString(src));
65,582✔
129
  }
65,582✔
130

131
  static const char* fromJson(JsonVariantConst src) {
62✔
132
    auto data = getData(src);
62✔
133
    return data ? data->asString().c_str() : 0;
62✔
134
  }
135

136
  static bool checkJson(JsonVariantConst src) {
43✔
137
    auto data = getData(src);
43✔
138
    return data && data->isString();
43✔
139
  }
140
};
141

142
template <>
143
struct Converter<JsonString> : private detail::VariantAttorney {
144
  static bool toJson(JsonString src, JsonVariant dst) {
41✔
145
    return getVariantImpl(dst).setString(detail::adaptString(src));
41✔
146
  }
147

148
  static JsonString fromJson(JsonVariantConst src) {
521✔
149
    auto data = getData(src);
521✔
150
    return data ? data->asString() : JsonString();
521✔
151
  }
152

153
  static bool checkJson(JsonVariantConst src) {
53✔
154
    auto data = getData(src);
53✔
155
    return data && data->isString();
53✔
156
  }
157
};
158

159
template <typename T>
160
inline detail::enable_if_t<detail::IsString<T>::value, bool> convertToJson(
498✔
161
    const T& src, JsonVariant dst) {
162
  return detail::VariantAttorney::getVariantImpl(dst).setString(
996✔
163
      detail::adaptString(src));
996✔
164
}
165

166
// SerializedValue<std::string>
167
// SerializedValue<String>
168
// SerializedValue<const __FlashStringHelper*>
169
template <typename T>
170
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
171
  static void toJson(SerializedValue<T> src, JsonVariant dst) {
36✔
172
    getVariantImpl(dst).setRawString(src);
36✔
173
  }
36✔
174
};
175

176
template <>
177
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
178
  static void toJson(detail::nullptr_t, JsonVariant dst) {
7✔
179
    getVariantImpl(dst).clear();
7✔
180
  }
7✔
181
  static detail::nullptr_t fromJson(JsonVariantConst) {
1✔
182
    return nullptr;
1✔
183
  }
184
  static bool checkJson(JsonVariantConst src) {
3✔
185
    auto data = getData(src);
3✔
186
    return data == 0 || data->isNull();
3✔
187
  }
188
};
189

190
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
191

192
namespace detail {
193
class StringBuilderPrint : public Print {
194
 public:
195
  StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
8✔
196
    copier_.startString();
8✔
197
  }
8✔
198

199
  void save(VariantData* data) {
4✔
200
    ARDUINOJSON_ASSERT(!overflowed());
201
    copier_.save(data);
4✔
202
  }
4✔
203

204
  size_t write(uint8_t c) {
52✔
205
    copier_.append(char(c));
52✔
206
    return copier_.isValid() ? 1 : 0;
52✔
207
  }
208

209
  size_t write(const uint8_t* buffer, size_t size) {
4✔
210
    for (size_t i = 0; i < size; i++) {
54✔
211
      copier_.append(char(buffer[i]));
52✔
212
      if (!copier_.isValid())
52✔
213
        return i;
2✔
214
    }
215
    return size;
2✔
216
  }
217

218
  bool overflowed() const {
8✔
219
    return !copier_.isValid();
8✔
220
  }
221

222
 private:
223
  StringBuilder copier_;
224
};
225
}  // namespace detail
226

227
inline void convertToJson(const ::Printable& src, JsonVariant dst) {
9✔
228
  auto resources = detail::VariantAttorney::getResourceManager(dst);
9✔
229
  auto data = detail::VariantAttorney::getData(dst);
9✔
230
  if (!resources || !data)
9✔
231
    return;
5✔
232
  detail::VariantImpl::clear(data, resources);
8✔
233
  detail::StringBuilderPrint print(resources);
8✔
234
  src.printTo(print);
8✔
235
  if (print.overflowed())
8✔
236
    return;
4✔
237
  print.save(data);
4✔
238
}
8✔
239

240
#endif
241

242
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
243

244
inline void convertFromJson(JsonVariantConst src, ::String& dst) {
245
  JsonString str = src.as<JsonString>();
246
  if (str)
247
    dst = str.c_str();
248
  else
249
    serializeJson(src, dst);
250
}
251

252
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
253
  return src.is<JsonString>();
254
}
255

256
#endif
257

258
#if ARDUINOJSON_ENABLE_STD_STRING
259

260
inline void convertFromJson(JsonVariantConst src, std::string& dst) {
465✔
261
  JsonString str = src.as<JsonString>();
465✔
262
  if (str)
465✔
263
    dst.assign(str.c_str(), str.size());
61✔
264
  else
265
    serializeJson(src, dst);
404✔
266
}
465✔
267

268
inline bool canConvertFromJson(JsonVariantConst src, const std::string&) {
21✔
269
  return src.is<JsonString>();
21✔
270
}
271

272
#endif
273

274
#if ARDUINOJSON_ENABLE_STRING_VIEW
275

276
inline void convertFromJson(JsonVariantConst src, std::string_view& dst) {
5✔
277
  JsonString str = src.as<JsonString>();
5✔
278
  if (str)  // the standard doesn't allow passing null to the constructor
5✔
279
    dst = std::string_view(str.c_str(), str.size());
4✔
280
}
5✔
281

282
inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
2✔
283
  return src.is<JsonString>();
2✔
284
}
285

286
#endif
287

288
template <>
289
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
290
  static void toJson(JsonArrayConst src, JsonVariant dst) {
3✔
291
    if (src.isNull())
3✔
UNCOV
292
      dst.set(nullptr);
×
293
    else
294
      dst.to<JsonArray>().set(src);
3✔
295
  }
3✔
296

297
  static JsonArrayConst fromJson(JsonVariantConst src) {
34✔
298
    return JsonArrayConst(getData(src), getResourceManager(src));
34✔
299
  }
300

301
  static bool checkJson(JsonVariantConst src) {
80✔
302
    auto data = getData(src);
80✔
303
    return data && data->isArray();
80✔
304
  }
305
};
306

307
template <>
308
struct Converter<JsonArray> : private detail::VariantAttorney {
309
  static void toJson(JsonVariantConst src, JsonVariant dst) {
11✔
310
    if (src.isNull())
11✔
311
      dst.set(nullptr);
1✔
312
    else
313
      dst.to<JsonArray>().set(src);
10✔
314
  }
11✔
315

316
  static JsonArray fromJson(JsonVariant src) {
76✔
317
    return JsonArray(getData(src), getResourceManager(src));
76✔
318
  }
319

320
  static bool checkJson(JsonVariant src) {
17✔
321
    auto data = getData(src);
17✔
322
    return data && data->isArray();
17✔
323
  }
324
};
325

326
template <>
327
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
328
  static void toJson(JsonVariantConst src, JsonVariant dst) {
9✔
329
    if (src.isNull())
9✔
UNCOV
330
      dst.set(nullptr);
×
331
    else
332
      dst.to<JsonObject>().set(src);
9✔
333
  }
9✔
334

335
  static JsonObjectConst fromJson(JsonVariantConst src) {
35✔
336
    return JsonObjectConst(getData(src), getResourceManager(src));
35✔
337
  }
338

339
  static bool checkJson(JsonVariantConst src) {
304✔
340
    auto data = getData(src);
304✔
341
    return data && data->isObject();
304✔
342
  }
343
};
344

345
template <>
346
struct Converter<JsonObject> : private detail::VariantAttorney {
347
  static void toJson(JsonVariantConst src, JsonVariant dst) {
18✔
348
    if (src.isNull())
18✔
349
      dst.set(nullptr);
1✔
350
    else
351
      dst.to<JsonObject>().set(src);
17✔
352
  }
18✔
353

354
  static JsonObject fromJson(JsonVariant src) {
103✔
355
    return JsonObject(getData(src), getResourceManager(src));
103✔
356
  }
357

358
  static bool checkJson(JsonVariant src) {
48✔
359
    auto data = getData(src);
48✔
360
    return data && data->isObject();
48✔
361
  }
362
};
363

364
ARDUINOJSON_END_PUBLIC_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc