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

bblanchon / ArduinoJson / 18653349747

20 Oct 2025 12:56PM UTC coverage: 99.34% (-0.08%) from 99.417%
18653349747

push

github

bblanchon
Return `bool` from all built-in `toJson` converters

104 of 108 new or added lines in 8 files covered. (96.3%)

3 existing lines in 2 files now uncovered.

3916 of 3942 relevant lines covered (99.34%)

10349.1 hits per line

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

97.96
/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 auto toJson(const T& src, JsonVariant dst)
520✔
29
      -> decltype(convertToJson(src, dst)) {
30
    // clang-format off
31
    return convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
520✔
32
    // clang-format on
33
  }
34

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

192
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
193

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

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

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

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

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

224
 private:
225
  StringBuilder copier_;
226
};
227
}  // namespace detail
228

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

243
#endif
244

245
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
246

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

255
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
256
  return src.is<JsonString>();
257
}
258

259
#endif
260

261
#if ARDUINOJSON_ENABLE_STD_STRING
262

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

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

275
#endif
276

277
#if ARDUINOJSON_ENABLE_STRING_VIEW
278

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

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

289
#endif
290

291
template <>
292
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
293
  static bool toJson(JsonArrayConst src, JsonVariant dst) {
3✔
294
    if (src.isNull())
3✔
NEW
295
      return dst.set(nullptr);
×
296
    else
297
      return dst.to<JsonArray>().set(src);
3✔
298
  }
299

300
  static JsonArrayConst fromJson(JsonVariantConst src) {
34✔
301
    return JsonArrayConst(getData(src), getResourceManager(src));
34✔
302
  }
303

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

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

319
  static JsonArray fromJson(JsonVariant src) {
76✔
320
    return JsonArray(getData(src), getResourceManager(src));
76✔
321
  }
322

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

329
template <>
330
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
331
  static bool toJson(JsonVariantConst src, JsonVariant dst) {
9✔
332
    if (src.isNull())
9✔
NEW
333
      return dst.set(nullptr);
×
334
    else
335
      return dst.to<JsonObject>().set(src);
9✔
336
  }
337

338
  static JsonObjectConst fromJson(JsonVariantConst src) {
35✔
339
    return JsonObjectConst(getData(src), getResourceManager(src));
35✔
340
  }
341

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

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

357
  static JsonObject fromJson(JsonVariant src) {
103✔
358
    return JsonObject(getData(src), getResourceManager(src));
103✔
359
  }
360

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

367
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