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: 2024-09-08 09:46:47 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              : 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          141 : format(
      93              :     core::string_view fmt,
      94              :     Args&&... args)
      95              : {
      96              :     return detail::vformat(
      97          141 :         fmt, detail::make_format_args(
      98          141 :             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            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            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 :     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
        

Generated by: LCOV version 2.1