Skip to content

Commit 52c9ae0

Browse files
committed
Add set_validated() helper
1 parent c0b9062 commit 52c9ae0

5 files changed

Lines changed: 230 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ SET (HEADERS
4848
include/dracosha/validator/interval.hpp
4949
include/dracosha/validator/range.hpp
5050
include/dracosha/validator/error.hpp
51+
include/dracosha/validator/set_validated.hpp
5152

5253
include/dracosha/validator/operators/operator.hpp
5354
include/dracosha/validator/operators/exists.hpp
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
@copyright Evgeny Sidorov 2020
3+
4+
Distributed under the Boost Software License, Version 1.0.
5+
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
6+
7+
*/
8+
9+
/****************************************************************************/
10+
11+
/** \file validator/validate.hpp
12+
*
13+
* Defines "set_validated" helpers.
14+
*
15+
*/
16+
17+
/****************************************************************************/
18+
19+
#ifndef DRACOSHA_VALIDATOR_SET_VALIDATED_HPP
20+
#define DRACOSHA_VALIDATOR_SET_VALIDATED_HPP
21+
22+
#include <dracosha/validator/validate.hpp>
23+
24+
DRACOSHA_VALIDATOR_NAMESPACE_BEGIN
25+
26+
/**
27+
* @brief Default implementation of member setter that uses [] to set element of container.
28+
*/
29+
template <typename ObjectT, typename MemberT>
30+
struct set_member_t
31+
{
32+
template <typename ObjectT1, typename MemberT1, typename ValueT>
33+
void operator() (
34+
ObjectT1& obj,
35+
MemberT1&& member,
36+
ValueT&& val
37+
) const
38+
{
39+
obj[std::forward<MemberT1>(member)]=std::forward<ValueT>(val);
40+
}
41+
};
42+
43+
/**
44+
* @brief Instantiation of member setter template.
45+
*/
46+
template <typename ObjectT, typename MemberT>
47+
constexpr set_member_t<ObjectT,MemberT> set_member_inst{};
48+
49+
/**
50+
* @brief Set object's member.
51+
* @param obj Object whose member to set.
52+
* @param member Member name, only single level members are supported.
53+
* @param val Value to set.
54+
*/
55+
template <typename ObjectT, typename MemberT, typename ValueT>
56+
void set_member(
57+
ObjectT& obj,
58+
MemberT&& member,
59+
ValueT&& val
60+
)
61+
{
62+
set_member_inst<std::decay_t<ObjectT>,std::decay_t<MemberT>>(obj,std::forward<MemberT>(member),std::forward<ValueT>(val));
63+
}
64+
65+
/**
66+
* @brief Set object's member with pre-validation with validation result put in the last argument.
67+
* @param obj Object whose member to set.
68+
* @param member Member name, only single level members are supported.
69+
* @param val Value to set.
70+
* @param validator Validator to use for validation.
71+
* @param err Validation result.
72+
*/
73+
template <typename ObjectT, typename MemberT, typename ValueT, typename ValidatorT>
74+
void set_validated(
75+
ObjectT& obj,
76+
MemberT&& member,
77+
ValueT&& val,
78+
ValidatorT&& validator,
79+
error_report& err
80+
)
81+
{
82+
validate(_[member],val,std::forward<ValidatorT>(validator),err);
83+
if (!err)
84+
{
85+
set_member(obj,member,std::forward<ValueT>(val));
86+
}
87+
}
88+
89+
/**
90+
* @brief Set object's member with pre-validation with exception if validation fails.
91+
* @param obj Object whose member to set.
92+
* @param member Member name, only single level members are supported.
93+
* @param val Value to set.
94+
* @param validator Validator to use for validation.
95+
*
96+
* @throws validation_error if validation fails.
97+
*/
98+
template <typename ObjectT, typename MemberT, typename ValueT, typename ValidatorT>
99+
void set_validated(
100+
ObjectT& obj,
101+
MemberT&& member,
102+
ValueT&& val,
103+
ValidatorT&& validator
104+
)
105+
{
106+
error_report err;
107+
set_validated(obj,std::forward<MemberT>(member),std::forward<ValueT>(val),std::forward<ValidatorT>(validator),err);
108+
if (err)
109+
{
110+
throw validation_error(err);
111+
}
112+
}
113+
114+
DRACOSHA_VALIDATOR_NAMESPACE_END
115+
116+
#endif // DRACOSHA_VALIDATOR_SET_VALIDATED_HPP

include/dracosha/validator/validate.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ struct validate_t
7777
* @brief Validate object with validator and throw validation_error if operation fails.
7878
* @brief obj Object to validate.
7979
* @brief validator Validator.
80+
*
81+
* @throws validation_error if validation fails.
8082
*/
8183
template <typename ObjectT, typename ValidatorT>
8284
void operator() (
@@ -121,6 +123,8 @@ struct validate_t
121123
* @brief member Path of the member to validate.
122124
* @brief obj Object to validate.
123125
* @brief validator Validator.
126+
*
127+
* @throws validation_error if validation fails.
124128
*/
125129
template <typename MemberT, typename ValueT, typename ValidatorT>
126130
void operator() (

test/test.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ SET(SOURCES
1616
${VALIDATOR_TEST_SRC}/testregex.cpp
1717
${VALIDATOR_TEST_SRC}/teststrnumbers.cpp
1818
${VALIDATOR_TEST_SRC}/testvalidate.cpp
19+
${VALIDATOR_TEST_SRC}/testsetvalidated.cpp
1920
)
2021

2122
SET (HEADERS

test/testsetvalidated.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include <boost/test/unit_test.hpp>
2+
3+
#include <dracosha/validator/validator.hpp>
4+
#include <dracosha/validator/set_validated.hpp>
5+
6+
DRACOSHA_VALIDATOR_PROPERTY(field1)
7+
8+
namespace {
9+
struct TestSetValidatorStruct
10+
{
11+
size_t field1=0;
12+
};
13+
}
14+
15+
DRACOSHA_VALIDATOR_NAMESPACE_BEGIN
16+
17+
template <>
18+
struct set_member_t<TestSetValidatorStruct,DRACOSHA_VALIDATOR_PROPERTY_TYPE(field1)>
19+
{
20+
template <typename ObjectT, typename MemberT, typename ValueT>
21+
void operator() (
22+
ObjectT& obj,
23+
MemberT&&,
24+
ValueT&& val
25+
) const
26+
{
27+
obj.field1=val;
28+
}
29+
};
30+
31+
DRACOSHA_VALIDATOR_NAMESPACE_END
32+
33+
using namespace DRACOSHA_VALIDATOR_NAMESPACE;
34+
35+
BOOST_AUTO_TEST_SUITE(TestSetValidated)
36+
37+
BOOST_AUTO_TEST_CASE(CheckSetValidatedContainer)
38+
{
39+
auto v=validator(
40+
_["field1"](gte,100)
41+
);
42+
43+
error_report err;
44+
45+
std::map<std::string,size_t> m;
46+
47+
set_validated(m,"field1",1000,v,err);
48+
BOOST_CHECK(!err);
49+
BOOST_REQUIRE(m.find("field1")!=m.end());
50+
BOOST_CHECK_EQUAL(m["field1"],1000);
51+
52+
set_validated(m,"field1",50,v,err);
53+
BOOST_CHECK(err);
54+
BOOST_REQUIRE(m.find("field1")!=m.end());
55+
BOOST_CHECK_EQUAL(m["field1"],1000);
56+
57+
BOOST_CHECK_NO_THROW(set_validated(m,"field1",300,v));
58+
BOOST_REQUIRE(m.find("field1")!=m.end());
59+
BOOST_CHECK_EQUAL(m["field1"],300);
60+
61+
BOOST_CHECK_THROW(set_validated(m,"field1",50,v),validation_error);
62+
try
63+
{
64+
set_validated(m,"field1",50,v);
65+
}
66+
catch (const validation_error& e)
67+
{
68+
BOOST_CHECK_EQUAL(e.what(),"field1 must be greater than or equal to 100");
69+
}
70+
71+
BOOST_REQUIRE(m.find("field1")!=m.end());
72+
BOOST_CHECK_EQUAL(m["field1"],300);
73+
}
74+
75+
BOOST_AUTO_TEST_CASE(CheckSetValidatedProperty)
76+
{
77+
auto v=validator(
78+
_[field1](gte,100)
79+
);
80+
81+
error_report err;
82+
TestSetValidatorStruct val;
83+
84+
set_validated(val,field1,1000,v,err);
85+
BOOST_CHECK(!err);
86+
BOOST_CHECK_EQUAL(val.field1,1000);
87+
88+
set_validated(val,field1,50,v,err);
89+
BOOST_CHECK(err);
90+
BOOST_CHECK_EQUAL(val.field1,1000);
91+
92+
BOOST_CHECK_NO_THROW(set_validated(val,field1,300,v));
93+
BOOST_CHECK_EQUAL(val.field1,300);
94+
95+
BOOST_CHECK_THROW(set_validated(val,field1,50,v),validation_error);
96+
try
97+
{
98+
set_validated(val,field1,50,v);
99+
}
100+
catch (const validation_error& e)
101+
{
102+
BOOST_CHECK_EQUAL(e.what(),"field1 must be greater than or equal to 100");
103+
}
104+
105+
BOOST_CHECK_EQUAL(val.field1,300);
106+
}
107+
108+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)