You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -116,11 +116,6 @@ Customizable validation implementer. Adapter performs actual validation when the
116
116
##### *Aggregation*
117
117
Combination of validating [operators](#operator) or other [validators](#validator) that make up a compound [validator](#validator). There are logical aggregations such as _AND_, _OR_, _NOT_ and [element](#element) aggregations such as _ANY_, _ALL_.
118
118
119
-
##### *Backend formatter*
120
-
String formatter used for [reports](#report) building. One of the following backend formatters can be used:
121
-
**(preferred)*[fmt](https://github.com/fmtlib/fmt) based backend formatter;
122
-
* std::stringstream based backend formatter.
123
-
124
119
##### *Concrete phrase*
125
120
Immutable string that will be used in final [report](#report).
126
121
@@ -1294,13 +1289,13 @@ There are three built-in adapter types implemented in `cpp-validator` library:
1294
1289
1295
1290
### Default adapter
1296
1291
1297
-
`Default adapter` wraps *lvalue* reference to the [object](#object) to be validated and invokes [operators](#operator) one by one as specified in a [validator](#validator). To make a `default adapter` call `make_default_adapter(object_to_validate)` with the [object](#object) as an argument. If a [validator](#validator) is applied directly to the [object](#object) then `default adapter` is constructed implicitly. See examples in [Using validator for data validation](#using-validator-for-data-validation) section.
1292
+
*Default adapter* wraps *lvalue* reference to the [object](#object) to be validated and invokes [operators](#operator) one by one as specified in a [validator](#validator). To make a *default adapter* call `make_default_adapter(object_to_validate)` with the [object](#object) as an argument. If a [validator](#validator) is applied directly to the [object](#object) then *default adapter* is constructed implicitly. See examples in [Using validator for data validation](#using-validator-for-data-validation) section.
1298
1293
1299
-
`Default adapter` supports implicit check of [member existence](#member-existence).
1294
+
*Default adapter* supports implicit check of [member existence](#member-existence).
1300
1295
1301
1296
### Single member adapter
1302
1297
1303
-
`Single member adapter` validates only a single member. This adapter is best suitable for *pre-validation*, i.e. validating the data before updating an object in the object's setters. `Single member adapter` is constructed by calling `make_single_member_adapter()` that can have one of the following signatures:
1298
+
*Single member adapter* validates only a single member. This adapter is best suitable for *pre-validation*, i.e. validating the data before updating an object in the object's setters. *Single member adapter* is constructed by calling `make_single_member_adapter()` helper that can have one of the following signatures:
1304
1299
-`make_single_member_adapter(member_path,val,reporter)` where
1305
1300
-`member_path` is a [member](#member) specified in [member notation](#member-notation);
1306
1301
-`val` is a variable to validate;
@@ -1310,7 +1305,7 @@ There are three built-in adapter types implemented in `cpp-validator` library:
1310
1305
-`val` is a variable to validate;
1311
1306
-`dst` destination object (e.g. string) where to put the validation [report](#report) to constructed with the default [reporter](#reporter) if validation fails.
1312
1307
1313
-
If the [member](#member) used in a `single member adapter` is not found in a [validator](#validator) then the validation will be considered as successful.
1308
+
If the [member](#member) used in a *single member adapter* is not found in a [validator](#validator) then the validation will be considered as successful.
1314
1309
1315
1310
See example of object setter with validation below.
1316
1311
@@ -1392,7 +1387,7 @@ Examples of *custom adapter* implementation can be found in `validator/adapters/
1392
1387
1393
1388
### Reporting adapter
1394
1389
1395
-
`Reporting adapter` does the same validation as [default adapter](#default-adapter) with addition of constructing a text [report](#report) describing the validation error. `Reporting adapter` is constructed by calling `make_reporting_adapter()` that can have one of the following signatures:
1390
+
*Reporting adapter* does the same validation as [default adapter](#default-adapter) with addition of constructing a text [report](#report) describing the validation error. *Reporting adapter* is constructed by calling `make_reporting_adapter()` that can have one of the following signatures:
1396
1391
-`make_reporting_adapter(object,reporter)` where
1397
1392
-`object` is an [object](#object) to validate;
1398
1393
-`reporter` is a custom [reporter](#reporter) used for [report](#report) constructing if validation fails;
@@ -1428,17 +1423,19 @@ return 0;
1428
1423
}
1429
1424
```
1430
1425
1431
-
`Reporting adapter` supports implicit check of [member existence](#member-existence).
1426
+
*Reporting adapter* supports implicit check of [member existence](#member-existence).
1432
1427
1433
1428
### Customization of reports
1434
1429
1435
1430
[Reports](#report) can be customized with help of custom [reporters](#reporter) that are given to adapters supporting [reports](#reports) construction.
1436
1431
1437
1432
#### Report construction
1438
1433
1439
-
A [report](#report) is constructed by a [reporter](#reporter) given to an adapter that supports [reports](#reports) construction. Default [reporter](#reporter) is implemented by `reporter` template class defined in `validator/reporting/reporter.hpp` header file. There are two ways to customize report construction:
1434
+
##### Default reporter
1435
+
1436
+
A [report](#report) is constructed by a [reporter](#reporter) given to an adapter that supports [reports](#reports) construction. *Default [reporter](#reporter)* is implemented by `reporter` template class defined in `validator/reporting/reporter.hpp` header file. There are two ways to customize report construction:
1440
1437
- implement a custom reporter *from scratch* and give it to the corresponding adapter;
1441
-
- use default `reporter` template class with custom [formatter](#formatter) - a helper function `make_reporter(report_destination,custom_formatter)` can be used for convenience, e.g.:
1438
+
- use default `reporter` template class with custom [formatter](#formatter), a helper function `make_reporter(report_destination,custom_formatter)` can be used for convenience, e.g.:
1442
1439
```cpp
1443
1440
1444
1441
// object_for_validation must be defined elsewhere
@@ -1447,22 +1444,151 @@ A [report](#report) is constructed by a [reporter](#reporter) given to an adapte
1447
1444
std::string report;
1448
1445
1449
1446
// create reporting adapter with custom report formatter
1450
-
autoreporting_adapter1=make_reporting_adapter(
1447
+
autora=make_reporting_adapter(
1451
1448
object_for_validation,
1452
1449
make_reporter(report,custom_formatter)
1453
1450
);
1454
1451
```
1452
+
##### Report with object's name
1453
+
1454
+
Typically, [report](#report) does not include a name of the object being validated. For example, `validator(gt,100)` will result in error message "must be greater than 100". If [report](#report) must include the object's name, e.g. "*the object under validation* must be greater than 100", then `reporter_with_object_name` must be used instead of [default reporter](#default-reporter). `reporter_with_object_name` template class is defined `validator/reporting/reporter_with_object_name.hpp` header file. A helper function `make_reporter_with_object_name()` can be used for convenience. See example below.
1455
+
1456
+
```cpp
1457
+
// object_for_validation must be defined elsewhere
1458
+
1459
+
std::string report;
1460
+
1461
+
// create reporting adapter with custom report formatter
1462
+
auto ra=make_reporting_adapter(
1463
+
object_for_validation,
1464
+
make_reporter_with_object_name(report,get_default_formatter(),"the object under validation")
1465
+
);
1466
+
```
1455
1467
1456
1468
#### Formatters
1457
1469
1470
+
[Formatter](#formatter) of [reports](#report) uses four components that can be customized:
1471
+
- [formatter of member names](#members-formatter);
1472
+
- [formatter of miscellaneous strings](#miscellaneous-strings-formatter) such as descriptions of [special](#special-operators) and [built-in](#built-in-operators) operators as well as keywords used in the library;
1473
+
- [formatter of operands](#operands-formatter);
1474
+
- traits that perform [final ordering and presentation](strings-order-and-presentation) of strings prepared with the partial formatters listed above.
1475
+
1476
+
Actual strings formatting is performed by a [backend formatter](backend-formatter).
1477
+
1478
+
Base `formatter` template class is defined in `validator/reporting/formatter.hpp` header file. Default *formatter* implementation can be obtained with `get_default_formatter()`.
1479
+
1480
+
Use `make_formatter()` helper to construct *formatters* with custom components and [translators](#translator). There is a number of `make_formatter()` signatures defined in `validator/reporting/formatter.hpp` header file, choose the most suitable for certain cases.
1481
+
1482
+
Reporting strings prepared with either top-level *formatter* or partial formatters can be overwritten with [reporting hints](#reporting-hints).
1483
+
1484
+
##### Backend formatter
1485
+
1486
+
*Backend formatter* is a *variable-to-string* formatter. One of the following string formatters can be used:
1487
+
- *(preferred)* [fmt](https://github.com/fmtlib/fmt) based backend formatter;
1488
+
- `std::stringstream` based backend formatter.
1489
+
1490
+
To use [fmt](https://github.com/fmtlib/fmt) for strings formatting define `DRACOSHA_VALIDATOR_FMT` macro, see [Building and installation](#building-and-installation) for details of formatter configuration.
1491
+
1458
1492
##### Members formatter
1459
1493
1494
+
[Reports](#report) must display human readable names of [members](#members). Member names formatting is performed by a *member names formatter* with base template class `member_names` defined in `validator/reporting/member_names.hpp` header file. For custom *member names formatting* the custom traits must be implemented and used as a template argument of `member_names`. There is `make_member_names()` helper to construct *member names formatter* from the custom traits.
1495
+
1496
+
Default implementation of *member names formatter* joins member names in reverse order using *of* conjunction, e.g. `["field1"]["subfield1_1"]["subfield1_1_1"]` will be formatted as "*subfield1_1_1 of subfield1_1 of field1*". Default member names formatter can be obtained with `get_default_member_names()`.
1497
+
1498
+
There is also `dotted_member_names` formatter that displays member names similar to their declaration, e.g. `["field1"]["subfield1_1"]["subfield1_1_1"]`` will be formatted as "*[field1].[subfield1_1].[subfield1_1_1]*".
1499
+
1500
+
If [localization](#localization) of member names must be supported then original *member names formatter* must be wrapped with *locale-aware member names formatter* using one of `make_translated_member_names()` helpers.
1501
+
1502
+
To [decorate](#decorator) member names the original *member names formatter* must be wrapped with *decorating member names formatter* using `make_decorated_member_names()` helper. See example below.
'"subfield1_1_1" of "subfield1_1" of "field1" must be greater than 100'
1528
+
*/
1529
+
}
1530
+
```
1531
+
1460
1532
##### Operands formatter
1461
1533
1534
+
By default [operands](#operand) are formatted at the discretion of [backend formatter](#backend-formatter). Sometimes [operands](#operand) may require special formatting. The obvious example is a boolean value which can be displayed in different ways, e.g. as 1/0, true/false, yes/not, checked/unchecked, etc. Another example is when the [operands](#operand) must be decorated, e.g. with quotes or HTML tags.
1535
+
1536
+
[Operands](#operand) formatting is performed by the *operands formatter* with base template class `operand_formatter` defined in `validator/reporting/operand_formatter.hpp` header file. For custom *operands formatting* the custom traits must be implemented and used as a template argument of `operand_formatter`. There is also `default_operand_formatter` which forwards operands to [backend formatter](#backend-formatter) "as is".
1537
+
1538
+
If [localization](#localization) of operands must be supported then *locale-aware operands formatter* must be used that can be constructed with one of `make_translated_operand_formatter()` helpers.
1539
+
1540
+
To [decorate](#decorator) operands the *decorating member names formatter* can be constructed with `make_operand_formatter()` or `make_translated_operand_formatter()` helpers. See example below.
1541
+
1542
+
```cpp
1543
+
// define validator
1544
+
auto v=validator(
1545
+
[size](gt,100)
1546
+
);
1547
+
1548
+
// operands formatter with quoted decorator
1549
+
auto decorated_operands=make_operand_formatter(quotes_decorator);
1550
+
1551
+
// object_for_validation must be defined elsewhere
1552
+
1553
+
std::string report;
1554
+
1555
+
// create reporting adapter with quoted member names
This formatter is used to format [operators](#operator) and some other strings.
1573
+
1574
+
Conversion of a generic *ID* to the string is performed as follows.
1575
+
- If string *ID* is a [property](#property) then `name()` of the [property](#property) is used.
1576
+
- If string *ID* is convertible to `std::string` then that conversion is used, e.g. all validation [operators](#operator) are formatted using the *to string conversion operator*.
1577
+
- If string *ID* is of some scalar type that can be forwarded to `std::to_string(id)` then `std::to_string()` is used.
1578
+
- In the rest cases "*\<?????\>*" string is used as a result.
1579
+
1580
+
After *ID* is converted to the string the conversion result goes to [translator](#translator). Translator returns either translated or original string.
1581
+
1582
+
Base template class `strings` for *miscellaneous strings formatting* is defined in `validator/reporting/strings.hpp` header file. Customization of *miscellaneous strings formatting* can be done with use of custom [translators](#translator) or *[aggregation](#aggregation) strings* which are used as template arguments in `strings` template class. Default *miscellaneous strings formatting* is implemented with `default_strings` formatter that uses default `aggregation_strings` formatter and no [translators](#translator).
1583
+
1584
+
If [localization](#localization) of miscellaneous strings must be supported then *locale-aware miscellaneous strings formatter* must be used that can be constructed with one of `make_translated_strings()` helpers.
1585
+
1464
1586
##### Strings order and presentation
1465
1587
1588
+
Resulting strings from the partial [formatters](#formatters) must be ordered and joined to construct the final [report](#report). By default that is performed by `default_order_and_presentation` helper defined in `validator/reporting/order_and_presentation.hpp` header file.
1589
+
1590
+
For custom strings ordering and presentation a custom implementation of the *strings order and presentation* must be used in `formatter` that can be constructed with corresponding `make_formatter()` helper.
1591
+
1466
1592
#### Decorator
1467
1593
1468
1594
Decorators can be used to decorate [members](#members-formatter) and [operands](#operands-formatter). For example, if one wants to mark [operands](#operands-formatter) with bold text using HTML tags to highlight them in user interface then a `decorator` that wraps operands with `<b>...</b>` might be implemented and used in [operands formatter](#operands-formatter). See examples of `decorator` use in [members formatter](#members-formatter) and [operands formatter](#operands-formatter) sections.
To override strings constructed by [reporter](#reporter) one can use *hints*. *Hint* is an explicit string that must be used in a [report](#report) for certain part of the report instead of automatically generated string.
1631
+
To override strings constructed by [formatters](#formatters) one can use *hints*. *Hint* is an explicit string that must be used in a [report](#report) for certain part of the report instead of automatically generated string.
0 commit comments