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

bblanchon / ArduinoJson / 9187151718

22 May 2024 07:27AM UTC coverage: 99.554% (+0.001%) from 99.553%
9187151718

push

github

bblanchon
Allow `Converter<T>::toJson()` to return a boolean as an optimization

27 of 27 new or added lines in 3 files covered. (100.0%)

2 existing lines in 1 file now uncovered.

3791 of 3808 relevant lines covered (99.55%)

11046.61 hits per line

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

98.88
/src/ArduinoJson/Variant/ConverterImpl.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2024, 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) {
144✔
29
    // clang-format off
30
    convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
144✔
31
    // clang-format on
32
  }
144✔
33

34
  static T fromJson(JsonVariantConst src) {
441✔
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/
440✔
40
    convertFromJson(src, result);  // Error here? See https://arduinojson.org/v7/unsupported-as/
441✔
41
    // clang-format on
42
    return result;
441✔
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();
46✔
50
    // clang-format off
51
    return canConvertFromJson(src, dummy);  // Error here? See https://arduinojson.org/v7/unsupported-is/
50✔
52
    // clang-format on
53
  }
54
};
55

56
template <typename T>
57
struct Converter<
58
    T, typename detail::enable_if<detail::is_integral<T>::value &&
59
                                  !detail::is_same<bool, T>::value &&
60
                                  !detail::is_same<char, T>::value>::type>
61
    : private detail::VariantAttorney {
62
  static bool toJson(T src, JsonVariant dst) {
1,028✔
63
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
64
    auto data = getData(dst);
1,028✔
65
    if (!data)
1,028✔
66
      return false;
24✔
67
    data->setInteger(src, getResourceManager(dst));
1,004✔
68
    return true;
1,004✔
69
  }
70

71
  static T fromJson(JsonVariantConst src) {
226✔
72
    ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
73
    auto data = getData(src);
226✔
74
    return data ? data->template asIntegral<T>() : T();
226✔
75
  }
76

77
  static bool checkJson(JsonVariantConst src) {
131✔
78
    auto data = getData(src);
131✔
79
    return data && data->template isInteger<T>();
131✔
80
  }
81
};
82

83
template <typename T>
84
struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
85
    : private detail::VariantAttorney {
86
  static bool toJson(T src, JsonVariant dst) {
1✔
87
    return dst.set(static_cast<JsonInteger>(src));
1✔
88
  }
89

90
  static T fromJson(JsonVariantConst src) {
1✔
91
    auto data = getData(src);
1✔
92
    return data ? static_cast<T>(data->template asIntegral<int>()) : T();
1✔
93
  }
94

95
  static bool checkJson(JsonVariantConst src) {
18✔
96
    auto data = getData(src);
18✔
97
    return data && data->template isInteger<int>();
18✔
98
  }
99
};
100

101
template <>
102
struct Converter<bool> : private detail::VariantAttorney {
103
  static bool toJson(bool src, JsonVariant dst) {
251✔
104
    auto data = getData(dst);
251✔
105
    if (!data)
251✔
106
      return false;
3✔
107
    data->setBoolean(src, getResourceManager(dst));
248✔
108
    return true;
248✔
109
  }
110

111
  static bool fromJson(JsonVariantConst src) {
1,248✔
112
    auto data = getData(src);
1,248✔
113
    return data ? data->asBoolean() : false;
1,248✔
114
  }
115

116
  static bool checkJson(JsonVariantConst src) {
38✔
117
    auto data = getData(src);
38✔
118
    return data && data->isBoolean();
38✔
119
  }
120
};
121

122
template <typename T>
123
struct Converter<
124
    T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
125
    : private detail::VariantAttorney {
126
  static bool toJson(T src, JsonVariant dst) {
63✔
127
    auto data = getData(dst);
63✔
128
    if (!data)
63✔
129
      return false;
2✔
130
    data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
61✔
131
    return true;
61✔
132
  }
133

134
  static T fromJson(JsonVariantConst src) {
118✔
135
    auto data = getData(src);
118✔
136
    return data ? data->template asFloat<T>() : 0;
118✔
137
  }
138

139
  static bool checkJson(JsonVariantConst src) {
45✔
140
    auto data = getData(src);
45✔
141
    return data && data->isFloat();
45✔
142
  }
143
};
144

145
template <>
146
struct Converter<const char*> : private detail::VariantAttorney {
147
  static void toJson(const char* src, JsonVariant dst) {
65,906✔
148
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
65,906✔
149
                                   getResourceManager(dst));
150
  }
65,906✔
151

152
  static const char* fromJson(JsonVariantConst src) {
61✔
153
    auto data = getData(src);
61✔
154
    return data ? data->asString().c_str() : 0;
61✔
155
  }
156

157
  static bool checkJson(JsonVariantConst src) {
47✔
158
    auto data = getData(src);
47✔
159
    return data && data->isString();
47✔
160
  }
161
};
162

163
template <>
164
struct Converter<JsonString> : private detail::VariantAttorney {
165
  static void toJson(JsonString src, JsonVariant dst) {
38✔
166
    detail::VariantData::setString(getData(dst), detail::adaptString(src),
38✔
167
                                   getResourceManager(dst));
168
  }
38✔
169

170
  static JsonString fromJson(JsonVariantConst src) {
466✔
171
    auto data = getData(src);
466✔
172
    return data ? data->asString() : 0;
466✔
173
  }
174

175
  static bool checkJson(JsonVariantConst src) {
39✔
176
    auto data = getData(src);
39✔
177
    return data && data->isString();
39✔
178
  }
179
};
180

181
template <typename T>
182
inline typename detail::enable_if<detail::IsString<T>::value>::type
183
convertToJson(const T& src, JsonVariant dst) {
123✔
184
  using namespace detail;
185
  auto data = VariantAttorney::getData(dst);
123✔
186
  auto resources = VariantAttorney::getResourceManager(dst);
123✔
187
  detail::VariantData::setString(data, adaptString(src), resources);
123✔
188
}
123✔
189

190
// SerializedValue<std::string>
191
// SerializedValue<String>
192
// SerializedValue<const __FlashStringHelper*>
193
template <typename T>
194
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
195
  static void toJson(SerializedValue<T> src, JsonVariant dst) {
37✔
196
    detail::VariantData::setRawString(getData(dst), src,
37✔
197
                                      getResourceManager(dst));
198
  }
37✔
199
};
200

201
template <>
202
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
203
  static void toJson(detail::nullptr_t, JsonVariant dst) {
6✔
204
    detail::VariantData::setNull(getData(dst), getResourceManager(dst));
6✔
205
  }
6✔
206
  static detail::nullptr_t fromJson(JsonVariantConst) {
1✔
207
    return nullptr;
1✔
208
  }
209
  static bool checkJson(JsonVariantConst src) {
3✔
210
    auto data = getData(src);
3✔
211
    return data == 0 || data->isNull();
3✔
212
  }
213
};
214

215
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
216

217
namespace detail {
218
class StringBuilderPrint : public Print {
219
 public:
220
  StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
8✔
221
    copier_.startString();
8✔
222
  }
8✔
223

224
  StringNode* save() {
4✔
225
    ARDUINOJSON_ASSERT(!overflowed());
226
    return copier_.save();
4✔
227
  }
228

229
  size_t write(uint8_t c) {
52✔
230
    copier_.append(char(c));
52✔
231
    return copier_.isValid() ? 1 : 0;
52✔
232
  }
233

234
  size_t write(const uint8_t* buffer, size_t size) {
4✔
235
    for (size_t i = 0; i < size; i++) {
54✔
236
      copier_.append(char(buffer[i]));
52✔
237
      if (!copier_.isValid())
52✔
238
        return i;
2✔
239
    }
240
    return size;
2✔
241
  }
242

243
  bool overflowed() const {
8✔
244
    return !copier_.isValid();
8✔
245
  }
246

247
 private:
248
  StringBuilder copier_;
249
};
250
}  // namespace detail
251

252
inline void convertToJson(const ::Printable& src, JsonVariant dst) {
9✔
253
  auto resources = detail::VariantAttorney::getResourceManager(dst);
9✔
254
  auto data = detail::VariantAttorney::getData(dst);
9✔
255
  if (!resources || !data)
9✔
256
    return;
5✔
257
  detail::StringBuilderPrint print(resources);
8✔
258
  src.printTo(print);
8✔
259
  if (print.overflowed()) {
8✔
260
    data->setNull();
4✔
261
    return;
4✔
262
  }
263
  data->setOwnedString(print.save());
4✔
264
}
265

266
#endif
267

268
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
269

270
inline void convertFromJson(JsonVariantConst src, ::String& dst) {
271
  JsonString str = src.as<JsonString>();
272
  if (str)
273
    dst = str.c_str();
274
  else
275
    serializeJson(src, dst);
276
}
277

278
inline bool canConvertFromJson(JsonVariantConst src, const ::String&) {
279
  return src.is<JsonString>();
280
}
281

282
#endif
283

284
#if ARDUINOJSON_ENABLE_STD_STRING
285

286
inline void convertFromJson(JsonVariantConst src, std::string& dst) {
435✔
287
  JsonString str = src.as<JsonString>();
435✔
288
  if (str)
435✔
289
    dst.assign(str.c_str(), str.size());
55✔
290
  else
291
    serializeJson(src, dst);
380✔
292
}
435✔
293

294
inline bool canConvertFromJson(JsonVariantConst src, const std::string&) {
21✔
295
  return src.is<JsonString>();
21✔
296
}
297

298
#endif
299

300
#if ARDUINOJSON_ENABLE_STRING_VIEW
301

302
inline void convertFromJson(JsonVariantConst src, std::string_view& dst) {
5✔
303
  JsonString str = src.as<JsonString>();
5✔
304
  if (str)  // the standard doesn't allow passing null to the constructor
5✔
305
    dst = std::string_view(str.c_str(), str.size());
4✔
306
}
5✔
307

308
inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
2✔
309
  return src.is<JsonString>();
2✔
310
}
311

312
#endif
313

314
template <>
315
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
316
  static void toJson(JsonArrayConst src, JsonVariant dst) {
3✔
317
    if (src.isNull())
3✔
UNCOV
318
      dst.set(nullptr);
×
319
    else
320
      dst.to<JsonArray>().set(src);
3✔
321
  }
3✔
322

323
  static JsonArrayConst fromJson(JsonVariantConst src) {
34✔
324
    auto data = getData(src);
34✔
325
    auto array = data ? data->asArray() : nullptr;
34✔
326
    return JsonArrayConst(array, getResourceManager(src));
34✔
327
  }
328

329
  static bool checkJson(JsonVariantConst src) {
80✔
330
    auto data = getData(src);
80✔
331
    return data && data->isArray();
80✔
332
  }
333
};
334

335
template <>
336
struct Converter<JsonArray> : private detail::VariantAttorney {
337
  static void toJson(JsonVariantConst src, JsonVariant dst) {
11✔
338
    if (src.isNull())
11✔
339
      dst.set(nullptr);
1✔
340
    else
341
      dst.to<JsonArray>().set(src);
10✔
342
  }
11✔
343

344
  static JsonArray fromJson(JsonVariant src) {
75✔
345
    auto data = getData(src);
75✔
346
    auto resources = getResourceManager(src);
75✔
347
    return JsonArray(data != 0 ? data->asArray() : 0, resources);
75✔
348
  }
349

350
  static bool checkJson(JsonVariant src) {
16✔
351
    auto data = getData(src);
16✔
352
    return data && data->isArray();
16✔
353
  }
354
};
355

356
template <>
357
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
358
  static void toJson(JsonVariantConst src, JsonVariant dst) {
9✔
359
    if (src.isNull())
9✔
UNCOV
360
      dst.set(nullptr);
×
361
    else
362
      dst.to<JsonObject>().set(src);
9✔
363
  }
9✔
364

365
  static JsonObjectConst fromJson(JsonVariantConst src) {
29✔
366
    auto data = getData(src);
29✔
367
    auto object = data != 0 ? data->asObject() : nullptr;
29✔
368
    return JsonObjectConst(object, getResourceManager(src));
29✔
369
  }
370

371
  static bool checkJson(JsonVariantConst src) {
303✔
372
    auto data = getData(src);
303✔
373
    return data && data->isObject();
303✔
374
  }
375
};
376

377
template <>
378
struct Converter<JsonObject> : private detail::VariantAttorney {
379
  static void toJson(JsonVariantConst src, JsonVariant dst) {
12✔
380
    if (src.isNull())
12✔
381
      dst.set(nullptr);
1✔
382
    else
383
      dst.to<JsonObject>().set(src);
11✔
384
  }
12✔
385

386
  static JsonObject fromJson(JsonVariant src) {
95✔
387
    auto data = getData(src);
95✔
388
    auto resources = getResourceManager(src);
95✔
389
    return JsonObject(data != 0 ? data->asObject() : 0, resources);
95✔
390
  }
391

392
  static bool checkJson(JsonVariant src) {
44✔
393
    auto data = getData(src);
44✔
394
    return data && data->isObject();
44✔
395
  }
396
};
397

398
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