@@ -169,19 +169,23 @@ class Array : public Base<Array<T, N, P>> {
169
169
return j;
170
170
}
171
171
172
- void validate (const Conf& c) const override {
172
+ bool validate (const Conf& c, std::optional<SchemaError>& err ) const override {
173
173
if (option_require_all_) {
174
- this ->validate_type (c);
175
- this ->validate_array (c);
176
- return ;
174
+ if (!this ->validate_type (c, err)) {
175
+ return false ;
176
+ }
177
+ if (!this ->validate_array (c, err)) {
178
+ return false ;
179
+ }
180
+ return true ;
177
181
}
178
182
179
183
if (c->type () == JsonType::array) {
180
- this ->validate_array (c);
184
+ return this ->validate_array (c, err );
181
185
} else if (c->type () == JsonType::object) {
182
- this ->validate_object (c);
186
+ return this ->validate_object (c, err );
183
187
} else {
184
- this ->throw_wrong_type ( c);
188
+ return this ->set_wrong_type (err, c);
185
189
}
186
190
}
187
191
@@ -233,7 +237,7 @@ class Array : public Base<Array<T, N, P>> {
233
237
} else if (c->type () == JsonType::object) {
234
238
this ->deserialize_from_object (v, c);
235
239
} else {
236
- this ->throw_wrong_type (c);
240
+ throw this ->wrong_type (c);
237
241
}
238
242
}
239
243
@@ -273,14 +277,17 @@ class Array : public Base<Array<T, N, P>> {
273
277
* That is, all elements in the array must be set, no less and
274
278
* no more.
275
279
*/
276
- void validate_array (const Conf& c) const {
280
+ bool validate_array (const Conf& c, std::optional<SchemaError>& err ) const {
277
281
assert (c->type () == JsonType::array);
278
282
if (c->size () != N) {
279
- this ->throw_error ( c, " require exactly {} items in array, got {}" , N, c->size ());
283
+ return this ->set_error (err, c, " require exactly {} items in array, got {}" , N, c->size ());
280
284
}
281
285
for (const auto & x : c.to_array ()) {
282
- prototype_.validate (x);
286
+ if (!prototype_.validate (x, err)) {
287
+ return false ;
288
+ }
283
289
}
290
+ return true ;
284
291
}
285
292
286
293
/* *
@@ -304,13 +311,16 @@ class Array : public Base<Array<T, N, P>> {
304
311
* less than the size N of the array. Otherwise an error is thrown.
305
312
* More than one index can be set at once. Unset indexes are left as is.
306
313
*/
307
- void validate_object (const Conf& c) const {
314
+ bool validate_object (const Conf& c, std::optional<SchemaError>& err ) const {
308
315
assert (c->type () == JsonType::object);
309
316
for (const auto & kv : c->items ()) {
310
317
const auto & key = kv.key ();
311
318
this ->parse_index (c, key);
312
- prototype_.validate (c.at (key));
319
+ if (prototype_.validate (c.at (key), err)) {
320
+ return false ;
321
+ }
313
322
}
323
+ return true ;
314
324
}
315
325
316
326
/* *
@@ -329,25 +339,25 @@ class Array : public Base<Array<T, N, P>> {
329
339
// We'd like to just be able to use std::stoul, but unfortunately
330
340
// the standard library seems to think strings like "234x" are ok.
331
341
if (s.empty ()) {
332
- this ->throw_error (c, " invalid index key in object, require integer, got ''" );
342
+ throw this ->error (c, " invalid index key in object, require integer, got ''" );
333
343
} else if (s.size () > 1 && s[0 ] == ' 0' ) {
334
- this ->throw_error (c, " invalid index key in object, require base-10 value, got '{}'" , s);
344
+ throw this ->error (c, " invalid index key in object, require base-10 value, got '{}'" , s);
335
345
}
336
346
for (char ch : s) {
337
347
if (ch < ' 0' || ch > ' 9' ) {
338
- this ->throw_error (c, " invalid index key in object, require integer, got '{}'" , s);
348
+ throw this ->error (c, " invalid index key in object, require integer, got '{}'" , s);
339
349
}
340
350
}
341
351
size_t idx = std::stoul (s);
342
352
if (idx >= N) {
343
- this ->throw_error (c, " out-of-range index key in object, require < {}, got '{}'" , N, s);
353
+ throw this ->error (c, " out-of-range index key in object, require < {}, got '{}'" , N, s);
344
354
}
345
355
return idx;
346
356
}
347
357
348
- [[noreturn ]] void throw_wrong_type (const Conf& c) const {
358
+ [[nodiscard ]] SchemaError wrong_type (const Conf& c) const {
349
359
std::string got = to_string (c->type ());
350
- this ->throw_error (c, " property must have type array or object, got {}" , got);
360
+ return this ->error (c, " property must have type array or object, got {}" , got);
351
361
}
352
362
353
363
void deserialize_from_object (Type& array, const Conf& c) const {
0 commit comments