LCOV - code coverage report
Current view: top level - boost/url - format.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 14 14 100.0 %
Date: 2024-03-13 19:32:03 Functions: 70 70 100.0 %

          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<detail::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<detail::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             : #ifdef BOOST_URL_DOCS
     404             : __implementation_defined__
     405             : #else
     406             : detail::named_arg<T>
     407             : #endif
     408          19 : arg(core::string_view name, T const& arg)
     409             : {
     410          19 :     return {name, arg};
     411             : }
     412             : 
     413             : } // url
     414             : } // boost
     415             : 
     416             : #endif

Generated by: LCOV version 1.15