|
19 | 19 | * [Property of object's member](#property-of-objects-member) |
20 | 20 | * [Mixed](#mixed) |
21 | 21 | * [Using validator for data validation](#using-validator-for-data-validation) |
| 22 | + * [Post-validation](#post-validation) |
| 23 | + * [validate() without report and without exception](#validate-without-report-and-without-exception) |
| 24 | + * [validate() with report but without exception](#validate-with-report-but-without-exception) |
| 25 | + * [validate() with exception](#validate-with-exception) |
| 26 | + * [Apply validator to adapter](#apply-validator-to-adapter) |
| 27 | + * [Apply validator to object](#apply-validator-to-object) |
| 28 | + * [Pre-validation](#pre-validation) |
22 | 29 | * [Members](#members) |
23 | 30 | * [Member notation](#member-notation) |
24 | 31 | * [Single level members](#single-level-members) |
@@ -245,7 +252,6 @@ auto v2=validator( |
245 | 252 | ``` |
246 | 253 | Validators *v1* and *v2* in the example above both define validation condition "size of field1 of variable must be greater than 100" where *field1* is a member of variable, *size* is a [property](#property) of *field1*, *gt* is an [operator](#operator) and *100* is an [operand](#operand). The first validator is described using property notation and the second validator is described using member notation. |
247 | 254 |
|
248 | | - |
249 | 255 | ### Validator with aggregations |
250 | 256 |
|
251 | 257 | #### Whole object |
@@ -322,6 +328,116 @@ The examples above define validation condition "size of variable is not equal to |
322 | 328 |
|
323 | 329 | ## Using validator for data validation |
324 | 330 |
|
| 331 | +### Post-validation |
| 332 | + |
| 333 | +*Post-validation* here stands for validating the object that is already populated with the data. The simplest way to validate an [object](#object) is to use `validate()` helper. There are forms `validate` with *exceptions* and without *exceptions*, with [report](#report) and without [report](#report). |
| 334 | + |
| 335 | +Also validation can be performed by calling `apply()` method of [validator](#validator), see the next sections. |
| 336 | + |
| 337 | +#### validate() without report and without exception |
| 338 | + |
| 339 | +```cpp |
| 340 | +#include <dracosha/validator/validator.hpp> |
| 341 | +#include <dracosha/validator/validate.hpp> |
| 342 | +using namespace DRACOSHA_VALIDATOR_NAMESPACE; |
| 343 | + |
| 344 | +int main() |
| 345 | +{ |
| 346 | + |
| 347 | +// define validator |
| 348 | +auto v=validator(gt,100); |
| 349 | + |
| 350 | +// validate variables |
| 351 | +error err; |
| 352 | + |
| 353 | +validate(90,v,err); |
| 354 | +if (err) |
| 355 | +{ |
| 356 | + // validation failed |
| 357 | +} |
| 358 | + |
| 359 | +validate(200,v,err)) |
| 360 | +if (!err) |
| 361 | +{ |
| 362 | + // validation succeeded |
| 363 | +} |
| 364 | + |
| 365 | +return 0; |
| 366 | +} |
| 367 | +``` |
| 368 | + |
| 369 | +#### validate() with report but without exception |
| 370 | + |
| 371 | +```cpp |
| 372 | +#include <dracosha/validator/validator.hpp> |
| 373 | +#include <dracosha/validator/validate.hpp> |
| 374 | +using namespace DRACOSHA_VALIDATOR_NAMESPACE; |
| 375 | + |
| 376 | +int main() |
| 377 | +{ |
| 378 | + |
| 379 | +// define validator |
| 380 | +auto v=validator(gt,100); |
| 381 | + |
| 382 | +// validate variables |
| 383 | +error_report err; |
| 384 | + |
| 385 | +validate(90,v,err); |
| 386 | +if (err) |
| 387 | +{ |
| 388 | + // validation failed |
| 389 | + std::cerr << err.message() << std::endl; |
| 390 | + /* prints: |
| 391 | + "must be greater than 100" |
| 392 | + */ |
| 393 | +} |
| 394 | + |
| 395 | +validate(200,v,err)) |
| 396 | +if (!err) |
| 397 | +{ |
| 398 | + // validation succeeded |
| 399 | +} |
| 400 | + |
| 401 | +return 0; |
| 402 | +} |
| 403 | +``` |
| 404 | + |
| 405 | +#### validate() with exception |
| 406 | + |
| 407 | +```cpp |
| 408 | +#include <dracosha/validator/validator.hpp> |
| 409 | +#include <dracosha/validator/validate.hpp> |
| 410 | +using namespace DRACOSHA_VALIDATOR_NAMESPACE; |
| 411 | + |
| 412 | +int main() |
| 413 | +{ |
| 414 | + |
| 415 | +// define validator |
| 416 | +auto v=validator(gt,100); |
| 417 | + |
| 418 | +// validate variables |
| 419 | + |
| 420 | +try |
| 421 | +{ |
| 422 | + validate(200,v); // succeed |
| 423 | + validate(90,v); // throw |
| 424 | +} |
| 425 | +catch (const validation_error& err) |
| 426 | +{ |
| 427 | + std::cerr << err.what() << std::endl; |
| 428 | + /* prints: |
| 429 | + |
| 430 | + "must be greater than 100" |
| 431 | + |
| 432 | + */ |
| 433 | +} |
| 434 | + |
| 435 | +return 0; |
| 436 | +} |
| 437 | +``` |
| 438 | + |
| 439 | +#### Apply validator to adapter |
| 440 | + |
325 | 441 | Data validation is performed by [adapters](#adapter). When a [validator](#validator) is applied to an [adapter](#adapter) the [adapter](#adapter) *reads* validation conditions from the [validator](#validator) and processes them depending on [adapter](#adapter) implementation. See more about adapters in [Adapters](#adapters) section. |
326 | 442 | ```cpp |
327 | 443 | #include <dracosha/validator/validator.hpp> |
@@ -353,6 +469,8 @@ return 0; |
353 | 469 | } |
354 | 470 | ``` |
355 | 471 |
|
| 472 | +#### Apply validator to object |
| 473 | + |
356 | 474 | A [validator](#validator) can be applied directly to a variable that must be validated. In this case a [default adapter](#default-adapter) will be used implicitly. |
357 | 475 | ```cpp |
358 | 476 | #include <dracosha/validator/validator.hpp> |
@@ -381,6 +499,95 @@ if (!v.apply(value2)) |
381 | 499 | return 0; |
382 | 500 | } |
383 | 501 | ``` |
| 502 | + |
| 503 | +### Pre-validation |
| 504 | + |
| 505 | +*Pre-validation* here stands for validating the data before writing it to the object. The simplest way to validate data before writing it to the object is to use `set_validated`. To customize data *pre-validation* use [single member adapter](#single-member-adapter). |
| 506 | + |
| 507 | +To use `set_validated` with custom [properties](#property) a template specialization of property setter `set_member_t` in `DRACOSHA_VALIDATOR_NAMESPACE` must be defined first. `set_validated` can be used both with and without exceptions. |
| 508 | + |
| 509 | +See examples below. |
| 510 | + |
| 511 | +```cpp |
| 512 | +#include <dracosha/validator/validator.hpp> |
| 513 | +#include <dracosha/validator/validate.hpp> |
| 514 | + |
| 515 | +// define structure with member variables and member setter method |
| 516 | +struct Foo |
| 517 | +{ |
| 518 | + std::string bar_value; |
| 519 | + |
| 520 | + uint32_t other_value; |
| 521 | + size_t some_size; |
| 522 | + |
| 523 | + void set_bar_value(std::string val) |
| 524 | + { |
| 525 | + bar_value=std::move(val); |
| 526 | + } |
| 527 | +}; |
| 528 | + |
| 529 | +// define custom properties |
| 530 | +DRACOSHA_VALIDATOR_PROPERTY(bar_value); |
| 531 | +DRACOSHA_VALIDATOR_PROPERTY(other_value); |
| 532 | + |
| 533 | +// template specialization for setting bar_value member of Foo |
| 534 | +DRACOSHA_VALIDATOR_NAMESPACE_BEGIN |
| 535 | + |
| 536 | +template <> |
| 537 | +struct set_member_t<Foo,DRACOSHA_VALIDATOR_PROPERTY_TYPE(bar_value)> |
| 538 | +{ |
| 539 | + template <typename ObjectT, typename MemberT, typename ValueT> |
| 540 | + void operator() ( |
| 541 | + ObjectT& obj, |
| 542 | + MemberT&&, |
| 543 | + ValueT&& val |
| 544 | + ) const |
| 545 | + { |
| 546 | + obj.set_bar_value(std::forward<ValueT>(val)); |
| 547 | + } |
| 548 | +}; |
| 549 | + |
| 550 | +DRACOSHA_VALIDATOR_NAMESPACE_END |
| 551 | + |
| 552 | +using namespace DRACOSHA_VALIDATOR_NAMESPACE; |
| 553 | + |
| 554 | +int main() |
| 555 | +{ |
| 556 | + |
| 557 | +// define validator of custom properties |
| 558 | +auto v=validator( |
| 559 | + _[bar_value](ilex_ne,"UNKNOWN"), // case insensitive lexicographical not equal |
| 560 | + _[other_value](gte,1000) |
| 561 | +); |
| 562 | + |
| 563 | +Foo foo_instance; |
| 564 | + |
| 565 | +error_report err; |
| 566 | + |
| 567 | +// call setter with valid data |
| 568 | +set_validated(foo_instance,bar_value,"Hello world",v,err); |
| 569 | +if (!err) |
| 570 | +{ |
| 571 | + // object's member is set |
| 572 | +} |
| 573 | + |
| 574 | +// call setter with invalid data |
| 575 | +set_validated(foo_instance,bar_value,"unknown",v,err); |
| 576 | +if (err) |
| 577 | +{ |
| 578 | + // object's member is not set |
| 579 | + std::cerr << err.message() << std::endl; |
| 580 | + /* prints: |
| 581 | + |
| 582 | + "bar_value must be not equal to UNKNOWN" |
| 583 | + |
| 584 | + */ |
| 585 | +} |
| 586 | + |
| 587 | +return 0; |
| 588 | +} |
| 589 | +``` |
| 590 | +
|
384 | 591 | ## Members |
385 | 592 |
|
386 | 593 | Members are used to define what parts of [objects](#object) must be validated. A [member](#member) can point to one of the following: |
@@ -469,9 +676,7 @@ if (!v.apply(ra)) |
469 | 676 | { |
470 | 677 | std::cerr << report << std::endl; |
471 | 678 | /* prints: |
472 | | - |
473 | 679 | "element #1 of field1 must be in range [10, 20, 30, 40, 50]" |
474 | | - |
475 | 680 | */ |
476 | 681 | } |
477 | 682 |
|
|
0 commit comments