1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
json_dto
*/
/*!
Some ready to use validators for typical cases.
*/
#pragma once
#include <json_dto/pub.hpp>
namespace json_dto
{
inline void
validator_error( const std::string & error_message )
{
throw ex_t{ error_message };
}
//
// min_max_validator_t
//
//! Validate value in [ a, b].
template < typename Number >
class min_max_validator_t
{
public:
min_max_validator_t( Number min_value, Number max_value )
: m_min_value{ min_value }
, m_max_value{ max_value }
{
if( m_min_value > m_max_value )
validator_error(
"invalid min-max validator: "
"max_value cannot be less than min_value" );
}
void
operator()( Number value ) const
{
if( m_min_value > value || m_max_value < value )
validator_error(
"invalid value: " + std::to_string( value ) +
", must be in "
"[ " + std::to_string( m_min_value ) +", " +
std::to_string( m_max_value ) +" ]" );
}
void
operator()( const std::vector< Number > & values ) const
{
for( auto v : values )
(*this)( v );
}
template< typename Field_Inner_Type >
void
operator()( const nullable_t< Field_Inner_Type > & value ) const
{
if( value )
(*this)( *value );
}
private:
Number m_min_value{};
Number m_max_value{};
};
template < typename Number >
auto
min_max_constraint( Number min_value, Number max_value )
{
return min_max_validator_t< Number >{min_value, max_value };
}
//
// one_of_validator_t
//
//! Validate in some predefined set.
template < typename Field_Type >
class one_of_validator_t
{
public:
one_of_validator_t( std::vector< Field_Type > values )
: m_values{ std::move( values ) }
{}
one_of_validator_t( std::initializer_list< Field_Type > values )
: m_values{ values }
{}
void
operator()( const Field_Type & value ) const
{
if( m_values.cend() ==
std::find( m_values.cbegin(), m_values.cend(), value ) )
{
validator_error( "invalid value, must be one of predefined values" );
}
}
void
operator()( const std::vector< Field_Type > & values ) const
{
for( auto v : values )
(*this)( v );
}
template< typename Field_Inner_Type >
void
operator()( const nullable_t< Field_Inner_Type > & value ) const
{
if( value )
(*this)( *value );
}
private:
std::vector< Field_Type > m_values{};
};
template < typename Field_Type >
auto
one_of_constraint( std::initializer_list< Field_Type > values )
{
return one_of_validator_t< Field_Type >{ values };
}
} /* namespace json_dto */
|