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_DETAIL_IMPL_REPLACEMENT_FIELD_RULE_IPP 11 : #define BOOST_URL_DETAIL_IMPL_REPLACEMENT_FIELD_RULE_IPP 12 : 13 : #include <boost/url/detail/config.hpp> 14 : #include "boost/url/detail/replacement_field_rule.hpp" 15 : #include <boost/url/grammar/alnum_chars.hpp> 16 : #include <boost/url/grammar/alpha_chars.hpp> 17 : #include <boost/url/grammar/delim_rule.hpp> 18 : #include <boost/url/grammar/lut_chars.hpp> 19 : #include <boost/url/grammar/optional_rule.hpp> 20 : #include <boost/url/grammar/parse.hpp> 21 : #include <boost/url/grammar/token_rule.hpp> 22 : #include <boost/url/grammar/tuple_rule.hpp> 23 : #include <boost/url/grammar/vchars.hpp> 24 : 25 : namespace boost { 26 : namespace urls { 27 : namespace detail { 28 : 29 : auto 30 673 : replacement_field_rule_t:: 31 : parse( 32 : char const*& it, 33 : char const* const end) const noexcept -> 34 : system::result<value_type> 35 : { 36 : static constexpr auto replacement_field_rules = 37 : grammar::tuple_rule( 38 : // open 39 : grammar::squelch( 40 : grammar::delim_rule('{')), 41 : // id 42 : grammar::optional_rule(arg_id_rule), 43 : // format options 44 : grammar::optional_rule( 45 : grammar::tuple_rule( 46 : grammar::squelch( 47 : grammar::delim_rule(':')), 48 : format_spec_rule)), 49 : // close 50 : grammar::squelch( 51 : grammar::delim_rule('}'))); 52 673 : auto it0 = it; 53 1346 : auto rv = grammar::parse(it, end, replacement_field_rules); 54 673 : if (!rv) 55 : { 56 328 : BOOST_URL_RETURN_EC( 57 : grammar::error::mismatch); 58 : } 59 345 : return core::string_view(it0, it); 60 : } 61 : 62 : auto 63 720 : identifier_rule_t:: 64 : parse( 65 : char const*& it, 66 : char const* const end) const noexcept 67 : -> system::result<value_type> 68 : { 69 : static constexpr auto identifier_rules = 70 : grammar::tuple_rule( 71 : grammar::delim_rule( 72 : grammar::alpha_chars + 73 : grammar::lut_chars('_')), 74 : grammar::optional_rule( 75 : grammar::token_rule( 76 : grammar::alnum_chars + 77 : grammar::lut_chars('_')))); 78 720 : char const* it0 = it; 79 1440 : auto rv = grammar::parse(it, end, identifier_rules); 80 720 : if (!rv) 81 : { 82 349 : BOOST_URL_RETURN_EC( 83 : grammar::error::mismatch); 84 : } 85 371 : return core::string_view(it0, it); 86 : } 87 : 88 : auto 89 86 : format_spec_rule_t:: 90 : parse( 91 : char const*& it, 92 : char const* const end) const noexcept 93 : -> system::result<value_type> 94 : { 95 86 : if (it == end) 96 2 : return {}; 97 : 98 : // any tokens allowed in fmt specs 99 : static constexpr auto fmt_specs_token_rule = 100 : grammar::optional_rule( 101 : grammar::token_rule( 102 : grammar::vchars + 103 : grammar::lut_chars(' ') 104 : - "{}")); 105 : 106 : // internal ids in the fmt specs 107 : // "{" [arg_id] "}" 108 : static constexpr auto internal_id_rule = 109 : grammar::tuple_rule( 110 : grammar::squelch( 111 : grammar::delim_rule('{')), 112 : grammar::optional_rule( 113 : arg_id_rule), 114 : grammar::squelch( 115 : grammar::delim_rule('}'))); 116 : 117 84 : auto start = it; 118 : // consume fmt_spec chars 119 112 : while (grammar::parse(it, end, fmt_specs_token_rule)) 120 : { 121 112 : auto it0 = it; 122 : // consume internal id 123 112 : if (!grammar::parse(it, end, internal_id_rule)) 124 : { 125 : // rewind 126 84 : it = it0; 127 84 : break; 128 : } 129 : } 130 : 131 84 : return core::string_view(start, it); 132 : } 133 : 134 : } // detail 135 : } // urls 136 : } // boost 137 : 138 : #endif