File: validators.hpp

package info (click to toggle)
restinio 0.6.19%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 8,184 kB
  • sloc: cpp: 110,712; ruby: 2,612; makefile: 22; sh: 21
file content (134 lines) | stat: -rw-r--r-- 2,520 bytes parent folder | download | duplicates (4)
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 */