Skip to content

Commit b60eebc

Browse files
committed
Write "Post-validation" and "Pre-validation" sections
1 parent f6fbb80 commit b60eebc

1 file changed

Lines changed: 208 additions & 3 deletions

File tree

docs/index.md

Lines changed: 208 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
* [Property of object's member](#property-of-objects-member)
2020
* [Mixed](#mixed)
2121
* [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)
2229
* [Members](#members)
2330
* [Member notation](#member-notation)
2431
* [Single level members](#single-level-members)
@@ -245,7 +252,6 @@ auto v2=validator(
245252
```
246253
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.
247254

248-
249255
### Validator with aggregations
250256

251257
#### Whole object
@@ -322,6 +328,116 @@ The examples above define validation condition "size of variable is not equal to
322328

323329
## Using validator for data validation
324330

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+
325441
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.
326442
```cpp
327443
#include <dracosha/validator/validator.hpp>
@@ -353,6 +469,8 @@ return 0;
353469
}
354470
```
355471

472+
#### Apply validator to object
473+
356474
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.
357475
```cpp
358476
#include <dracosha/validator/validator.hpp>
@@ -381,6 +499,95 @@ if (!v.apply(value2))
381499
return 0;
382500
}
383501
```
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+
384591
## Members
385592
386593
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))
469676
{
470677
std::cerr << report << std::endl;
471678
/* prints:
472-
473679
"element #1 of field1 must be in range [10, 20, 30, 40, 50]"
474-
475680
*/
476681
}
477682

0 commit comments

Comments
 (0)