LCOV - code coverage report
Current view: top level - boost/url/format.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 14 14
Test Date: 2025-01-10 18:07:09 Functions: 100.0 % 70 70

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

Generated by: LCOV version 2.1