GCC Code Coverage Report


Directory: libs/url/
File: boost/url/format.hpp
Date: 2024-08-20 16:05:55
Exec Total Coverage
Lines: 14 14 100.0%
Functions: 64 64 100.0%
Branches: 6 8 75.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/url
8 //
9
10 #ifndef BOOST_URL_FORMAT_HPP
11 #define BOOST_URL_FORMAT_HPP
12
13 #include <boost/url/detail/config.hpp>
14 #include <boost/core/detail/string_view.hpp>
15 #include <boost/url/url.hpp>
16 #include <boost/url/detail/vformat.hpp>
17 #include <initializer_list>
18
19 namespace boost {
20 namespace urls {
21
22 /** Format arguments into a URL
23
24 Format arguments according to the format
25 URL string into a @ref url.
26
27 The rules for a format URL string are the same
28 as for a `std::format_string`, where replacement
29 fields are delimited by curly braces.
30
31 The URL components to which replacement fields
32 belong are identified before replacement is
33 applied and any invalid characters for that
34 formatted argument are percent-escaped.
35
36 Hence, the delimiters between URL components,
37 such as `:`, `//`, `?`, and `#`, should be
38 included in the URL format string. Likewise,
39 a format string with a single `"{}"` is
40 interpreted as a path and any replacement
41 characters invalid in this component will be
42 encoded to form a valid URL.
43
44 @par Example
45 @code
46 assert(format("{}", "Hello world!").buffer() == "Hello%20world%21");
47 @endcode
48
49 @par Preconditions
50 All replacement fields must be valid and the
51 resulting URL should be valid after arguments
52 are formatted into the URL.
53
54 Because any invalid characters for a URL
55 component are encoded by this function, only
56 replacements in the scheme and port components
57 might be invalid, as these components do not
58 allow percent-encoding of arbitrary
59 characters.
60
61 @return A URL holding the formatted result.
62
63 @param fmt The format URL string.
64 @param args Arguments to be formatted.
65
66 @throws system_error
67 `fmt` contains an invalid format string and
68 the result contains an invalid URL after
69 replacements are applied.
70
71 @par BNF
72 @code
73 replacement_field ::= "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
74 arg_id ::= integer | identifier
75 integer ::= digit+
76 digit ::= "0"..."9"
77 identifier ::= id_start id_continue*
78 id_start ::= "a"..."z" | "A"..."Z" | "_"
79 id_continue ::= id_start | digit
80 @endcode
81
82 @par Specification
83 @li <a href="https://fmt.dev/latest/syntax.html"
84 >Format String Syntax</a>
85
86 @see
87 @ref format_to.
88
89 */
90 template <class... Args>
91 url
92 282 format(
93 core::string_view fmt,
94 Args&&... args)
95 {
96 return detail::vformat(
97 282 fmt, detail::make_format_args(
98
2/2
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 10 times.
282 std::forward<Args>(args)...));
99 }
100
101 /** Format arguments into a URL
102
103 Format arguments according to the format
104 URL string into a @ref url_base.
105
106 The rules for a format URL string are the same
107 as for a `std::format_string`, where replacement
108 fields are delimited by curly braces.
109
110 The URL components to which replacement fields
111 belong are identified before replacement is
112 applied and any invalid characters for that
113 formatted argument are percent-escaped.
114
115 Hence, the delimiters between URL components,
116 such as `:`, `//`, `?`, and `#`, should be
117 included in the URL format string. Likewise,
118 a format string with a single `"{}"` is
119 interpreted as a path and any replacement
120 characters invalid in this component will be
121 encoded to form a valid URL.
122
123 @par Example
124 @code
125 static_url<30> u;
126 format(u, "{}", "Hello world!");
127 assert(u.buffer() == "Hello%20world%21");
128 @endcode
129
130 @par Preconditions
131 All replacement fields must be valid and the
132 resulting URL should be valid after arguments
133 are formatted into the URL.
134
135 Because any invalid characters for a URL
136 component are encoded by this function, only
137 replacements in the scheme and port components
138 might be invalid, as these components do not
139 allow percent-encoding of arbitrary
140 characters.
141
142 @par Exception Safety
143 Strong guarantee.
144
145 @param u An object that derives from @ref url_base.
146 @param fmt The format URL string.
147 @param args Arguments to be formatted.
148
149 @throws system_error
150 `fmt` contains an invalid format string and
151 `u` contains an invalid URL after replacements
152 are applied.
153
154 @par BNF
155 @code
156 replacement_field ::= "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
157 arg_id ::= integer | identifier
158 integer ::= digit+
159 digit ::= "0"..."9"
160 identifier ::= id_start id_continue*
161 id_start ::= "a"..."z" | "A"..."Z" | "_"
162 id_continue ::= id_start | digit
163 @endcode
164
165 @par Specification
166 @li <a href="https://fmt.dev/latest/syntax.html"
167 >Format String Syntax</a>
168
169 @see
170 @ref format.
171
172 */
173 template <class... Args>
174 void
175 3 format_to(
176 url_base& u,
177 core::string_view fmt,
178 Args&&... args)
179 {
180
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
3 detail::vformat_to(
181 3 u, fmt, detail::make_format_args(
182 std::forward<Args>(args)...));
183 2 }
184
185 /** Format arguments into a URL
186
187 Format arguments according to the format
188 URL string into a @ref url.
189
190 This overload allows type-erased arguments
191 to be passed as an initializer_list, which
192 is mostly convenient for named parameters.
193
194 All arguments must be convertible to a
195 implementation defined type able to store a
196 type-erased reference to any valid format
197 argument.
198
199 The rules for a format URL string are the same
200 as for a `std::format_string`, where replacement
201 fields are delimited by curly braces.
202
203 The URL components to which replacement fields
204 belong are identified before replacement is
205 applied and any invalid characters for that
206 formatted argument are percent-escaped.
207
208 Hence, the delimiters between URL components,
209 such as `:`, `//`, `?`, and `#`, should be
210 included in the URL format string. Likewise,
211 a format string with a single `"{}"` is
212 interpreted as a path and any replacement
213 characters invalid in this component will be
214 encoded to form a valid URL.
215
216 @par Example
217 @code
218 assert(format("user/{id}", {{"id", 1}}).buffer() == "user/1");
219 @endcode
220
221 @par Preconditions
222 All replacement fields must be valid and the
223 resulting URL should be valid after arguments
224 are formatted into the URL.
225
226 Because any invalid characters for a URL
227 component are encoded by this function, only
228 replacements in the scheme and port components
229 might be invalid, as these components do not
230 allow percent-encoding of arbitrary
231 characters.
232
233 @return A URL holding the formatted result.
234
235 @param fmt The format URL string.
236 @param args Arguments to be formatted.
237
238 @throws system_error
239 `fmt` contains an invalid format string and
240 the result contains an invalid URL after
241 replacements are applied.
242
243 @par BNF
244 @code
245 replacement_field ::= "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
246 arg_id ::= integer | identifier
247 integer ::= digit+
248 digit ::= "0"..."9"
249 identifier ::= id_start id_continue*
250 id_start ::= "a"..."z" | "A"..."Z" | "_"
251 id_continue ::= id_start | digit
252 @endcode
253
254 @par Specification
255 @li <a href="https://fmt.dev/latest/syntax.html"
256 >Format String Syntax</a>
257
258 @see
259 @ref format_to.
260
261 */
262 inline
263 url
264 2 format(
265 core::string_view fmt,
266 #ifdef BOOST_URL_DOCS
267 std::initializer_list<__see_below__> args
268 #else
269 std::initializer_list<see_below::format_arg> args
270 #endif
271 )
272 {
273 return detail::vformat(
274 fmt, detail::format_args(
275
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 args.begin(), args.end()));
276 }
277
278 /** Format arguments into a URL
279
280 Format arguments according to the format
281 URL string into a @ref url_base.
282
283 This overload allows type-erased arguments
284 to be passed as an initializer_list, which
285 is mostly convenient for named parameters.
286
287 All arguments must be convertible to a
288 implementation defined type able to store a
289 type-erased reference to any valid format
290 argument.
291
292 The rules for a format URL string are the same
293 as for a `std::format_string`, where replacement
294 fields are delimited by curly braces.
295
296 The URL components to which replacement fields
297 belong are identified before replacement is
298 applied and any invalid characters for that
299 formatted argument are percent-escaped.
300
301 Hence, the delimiters between URL components,
302 such as `:`, `//`, `?`, and `#`, should be
303 included in the URL format string. Likewise,
304 a format string with a single `"{}"` is
305 interpreted as a path and any replacement
306 characters invalid in this component will be
307 encoded to form a valid URL.
308
309 @par Example
310 @code
311 static_url<30> u;
312 format_to(u, "user/{id}", {{"id", 1}})
313 assert(u.buffer() == "user/1");
314 @endcode
315
316 @par Preconditions
317 All replacement fields must be valid and the
318 resulting URL should be valid after arguments
319 are formatted into the URL.
320
321 Because any invalid characters for a URL
322 component are encoded by this function, only
323 replacements in the scheme and port components
324 might be invalid, as these components do not
325 allow percent-encoding of arbitrary
326 characters.
327
328 @par Exception Safety
329 Strong guarantee.
330
331 @param u An object that derives from @ref url_base.
332 @param fmt The format URL string.
333 @param args Arguments to be formatted.
334
335 @throws system_error
336 `fmt` contains an invalid format string and
337 `u` contains an invalid URL after replacements
338 are applied.
339
340 @par BNF
341 @code
342 replacement_field ::= "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
343 arg_id ::= integer | identifier
344 integer ::= digit+
345 digit ::= "0"..."9"
346 identifier ::= id_start id_continue*
347 id_start ::= "a"..."z" | "A"..."Z" | "_"
348 id_continue ::= id_start | digit
349 @endcode
350
351 @par Specification
352 @li <a href="https://fmt.dev/latest/syntax.html"
353 >Format String Syntax</a>
354
355 @see
356 @ref format.
357
358 */
359 inline
360 void
361 1 format_to(
362 url_base& u,
363 core::string_view fmt,
364 #ifdef BOOST_URL_DOCS
365 std::initializer_list<__see_below__> args
366 #else
367 std::initializer_list<see_below::format_arg> args
368 #endif
369 )
370 {
371
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 detail::vformat_to(
372 u, fmt, detail::format_args(
373 args.begin(), args.end()));
374 1 }
375
376 /** Designate a named argument for a replacement field
377
378 Construct a named argument for a format URL
379 string that contains named replacement fields.
380
381 The function parameters should be convertible
382 to an implementation defined type able to
383 store the name and a reference to any type
384 potentially used as a format argument.
385
386 @par Example
387 @code
388 assert(format("user/{id}", arg("id", 1)).buffer() == "user/1");
389 @endcode
390
391 @return An temporary object with reference
392 semantics for a named argument
393
394 @param name The argument name
395 @param arg The argument value
396
397 @see
398 @ref format,
399 @ref format_to.
400
401 */
402 template <class T>
403 BOOST_URL_IMPLEMENTATION_DEFINED(implementation_defined::named_arg<T>)
404 19 arg(core::string_view name, T const& arg)
405 {
406 19 return {name, arg};
407 }
408
409 } // url
410 } // boost
411
412 #endif
413