RESTinio
try_parse_field.hpp
Go to the documentation of this file.
1 /*
2  * RESTinio
3  */
4 
5 /*!
6  * @file
7  * @brief Helper functions for parsing values of HTTP-fields.
8  *
9  * @since v.0.6.8
10  */
11 
12 #pragma once
13 
14 #include <restinio/helpers/easy_parser.hpp>
15 
16 #include <restinio/http_headers.hpp>
17 #include <restinio/request_handler.hpp>
18 #include <restinio/variant.hpp>
19 
20 #include <iostream>
21 
22 namespace restinio
23 {
24 
25 namespace http_field_parsers
26 {
27 
28 //
29 // field_not_found_t
30 //
31 /*!
32  * @brief A special type to be returned in the case if HTTP-field
33  * isn't found in a request.
34  *
35  * @since v.0.6.8
36  */
38 
40 {
41 
42 //
43 // result_variant_t
44 //
45 /*!
46  * @brief Type of a variant to be returned as the result of attempt
47  * to parse HTTP-field.
48  *
49  * @since v.0.6.8
50  */
51 template< typename Parsed_Field_Type >
56 
57 //
58 // valid_field_type
59 //
60 template< typename, typename = restinio::utils::metaprogramming::void_t<> >
61 struct valid_field_type : public std::false_type {};
62 
63 template< typename T >
65  T,
68  std::is_same<
70  decltype(T::try_parse(std::declval<string_view_t>()))
71  >::value,
72  bool
73  >
74  >
75  > : public std::true_type
76 {};
77 
78 //
79 // try_extract_field_value_from
80 //
81 template< typename Parsed_Field_Type >
82 RESTINIO_NODISCARD
83 result_variant_t< Parsed_Field_Type >
87 {
88  static_assert( valid_field_type<Parsed_Field_Type>::value,
89  "Parsed_Field_Type should have static try_parse method that "
90  "accepts string_view_t and returns "
91  "expected_t<Parsed_Field_Type, parse_error_t>" );
92 
93  if( !opt_value && default_value.empty() )
94  return { field_not_found_t{} };
95 
97 
99  if( parse_result )
100  return { std::move(*parse_result) };
101  else
102  return { parse_result.error() };
103 }
104 
105 } /* namespace try_extract_field_details */
106 
107 //
108 // try_parse_field
109 //
110 /*!
111  * @brief A helper function for extraction and parsing a value of
112  * HTTP-field.
113  *
114  * This helper is intended to be used when HTTP-field is identified
115  * by its name.
116  *
117  * Usage example:
118  * @code
119  * auto on_post(const restinio::request_handle_t & req) {
120  * using namespace restinio::http_field_parsers;
121  *
122  * const auto auth_field = try_parse_field< authorization_value_t >(
123  * req, "X-My-Authorization");
124  * if(auto * auth = restinio::get_if<authorization_value_t>(&auth_field)) {
125  * // X-My-Authorization is successfully parsed.
126  * if("basic" == auth->auth_scheme) {
127  * ... // Dealing with basic authentification.
128  * }
129  * else if("bearer" == auth->auth_scheme) {
130  * ... // Dealing with bearer authentification.
131  * }
132  * else {
133  * ...
134  * }
135  * }
136  * }
137  * @endcode
138  *
139  * @tparam Parsed_Field_Type The type of field value to be received as the
140  * result of successful parse if the field is present.
141  *
142  * @tparam Extra_Data The type of extra-data incorporated into an instance
143  * of restinio::generic_request_t. There is no need to specify that type,
144  * it has to be detected automatically by the compiler.
145  *
146  * @since v.0.6.8
147  */
148 template< typename Parsed_Field_Type, typename Extra_Data >
150 auto
152  //! A request that should hold a HTTP-field.
153  const generic_request_t< Extra_Data > & req,
154  //! The name of HTTP-field to be extracted and parsed.
156  //! The default value to be used if HTTP-field is not found.
157  //! If this value is not empty, then the variant with
158  //! field_not_found_t won't be returned.
160 {
161  using namespace try_extract_field_details;
162 
165  default_value );
166 }
167 
168 /*!
169  * @brief A helper function for extraction and parsing a value of
170  * HTTP-field.
171  *
172  * This helper is intended to be used when HTTP-field is identified
173  * by its ID.
174  *
175  * Usage example:
176  * @code
177  * auto on_post(const restinio::request_handle_t & req) {
178  * using namespace restinio::http_field_parsers;
179  *
180  * const auto auth_field = try_parse_field< authorization_value_t >(
181  * req, restinio::http_field::authorization);
182  * if(auto * auth = restinio::get_if<authorization_value_t>(&auth_field)) {
183  * // Authorization is successfully parsed.
184  * if("basic" == auth->auth_scheme) {
185  * ... // Dealing with basic authentification.
186  * }
187  * else if("bearer" == auth->auth_scheme) {
188  * ... // Dealing with bearer authentification.
189  * }
190  * else {
191  * ...
192  * }
193  * }
194  * }
195  * @endcode
196  *
197  * @tparam Parsed_Field_Type The type of field value to be received as the
198  * result of successful parse if the field is present.
199  *
200  * @tparam Extra_Data The type of extra-data incorporated into an instance
201  * of restinio::generic_request_t. There is no need to specify that type,
202  * it has to be detected automatically by the compiler.
203  *
204  * @since v.0.6.8
205  */
206 template< typename Parsed_Field_Type, typename Extra_Data >
208 auto
210  //! A request that should hold a HTTP-field.
211  const generic_request_t< Extra_Data > & req,
212  //! The ID of a HTTP-field to be extracted and parsed.
214  //! The default value to be used if HTTP-field is not found.
215  //! If this value is not empty, then the variant with
216  //! field_not_found_t won't be returned.
218 {
219  using namespace try_extract_field_details;
220 
223  default_value );
224 }
225 
226 } /* namespace http_field_parsers */
227 
228 } /* namespace restinio */
RESTINIO_NODISCARD result_variant_t< Parsed_Field_Type > try_extract_field_value_from(optional_t< string_view_t > opt_value, string_view_t default_value)
RESTINIO_NODISCARD auto try_parse_field(const generic_request_t< Extra_Data > &req, http_field_t field_id, string_view_t default_value=string_view_t{})
A helper function for extraction and parsing a value of HTTP-field.
A special type to be returned in the case if HTTP-field isn&#39;t found in a request. ...
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
Definition: value_or.hpp:64