RESTinio
Loading...
Searching...
No Matches
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
19#include <iostream>
20#include <variant>
21
22namespace restinio
23{
24
25namespace 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 */
51template< typename Parsed_Field_Type >
52using result_variant_t = std::variant<
53 Parsed_Field_Type,
56
57//
58// valid_field_type
59//
60template< typename, typename = restinio::utils::metaprogramming::void_t<> >
61struct valid_field_type : public std::false_type {};
62
63template< 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//
81template< typename Parsed_Field_Type >
82[[nodiscard]]
85 std::optional< string_view_t > opt_value,
86 string_view_t default_value )
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
96 string_view_t content = opt_value ? *opt_value : default_value;
97
98 auto parse_result = Parsed_Field_Type::try_parse( content );
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 = std::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 */
148template< typename Parsed_Field_Type, typename Extra_Data >
149[[nodiscard]]
150auto
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.
155 string_view_t field_name,
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.
159 string_view_t default_value = string_view_t{} )
160{
161 using namespace try_extract_field_details;
162
163 return try_extract_field_value_from< Parsed_Field_Type >(
164 req.header().opt_value_of( field_name ),
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 = std::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 */
206template< typename Parsed_Field_Type, typename Extra_Data >
207[[nodiscard]]
208auto
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.
213 http_field_t field_id,
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.
217 string_view_t default_value = string_view_t{} )
218{
219 using namespace try_extract_field_details;
220
221 return try_extract_field_value_from< Parsed_Field_Type >(
222 req.header().opt_value_of( field_id ),
223 default_value );
224}
225
226} /* namespace http_field_parsers */
227
228} /* namespace restinio */
Information about parsing error.
result_variant_t< Parsed_Field_Type > try_extract_field_value_from(std::optional< string_view_t > opt_value, string_view_t default_value)
std::variant< Parsed_Field_Type, field_not_found_t, restinio::easy_parser::parse_error_t > result_variant_t
Type of a variant to be returned as the result of attempt to parse HTTP-field.
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.
auto try_parse_field(const generic_request_t< Extra_Data > &req, string_view_t field_name, string_view_t default_value=string_view_t{})
A helper function for extraction and parsing a value of HTTP-field.
http_field_t
C++ enum that repeats nodejs c-style enum.
A special type to be returned in the case if HTTP-field isn't found in a request.