1  
//
1  
//
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/http
7  
// Official repository: https://github.com/cppalliance/http
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_HTTP_RFC_LIST_RULE_HPP
10  
#ifndef BOOST_HTTP_RFC_LIST_RULE_HPP
11  
#define BOOST_HTTP_RFC_LIST_RULE_HPP
11  
#define BOOST_HTTP_RFC_LIST_RULE_HPP
12  

12  

13  
#include <boost/http/detail/config.hpp>
13  
#include <boost/http/detail/config.hpp>
14  
#include <boost/url/grammar/range_rule.hpp>
14  
#include <boost/url/grammar/range_rule.hpp>
15  
#include <boost/core/empty_value.hpp>
15  
#include <boost/core/empty_value.hpp>
16  

16  

17  
namespace boost {
17  
namespace boost {
18  
namespace http {
18  
namespace http {
19  

19  

20  
namespace implementation_defined {
20  
namespace implementation_defined {
21  
template<class Rule>
21  
template<class Rule>
22  
struct list_rule_t
22  
struct list_rule_t
23  
    : private empty_value<Rule>
23  
    : private empty_value<Rule>
24  
{
24  
{
25  
    using value_type = grammar::range<
25  
    using value_type = grammar::range<
26  
        typename Rule::value_type>;
26  
        typename Rule::value_type>;
27  

27  

28  
    constexpr
28  
    constexpr
29  
    list_rule_t(
29  
    list_rule_t(
30  
        Rule const& r,
30  
        Rule const& r,
31  
        std::size_t n,
31  
        std::size_t n,
32  
        std::size_t m) noexcept
32  
        std::size_t m) noexcept
33  
        : empty_value<Rule>(
33  
        : empty_value<Rule>(
34  
            empty_init, r)
34  
            empty_init, r)
35  
        , n_(n)
35  
        , n_(n)
36  
        , m_(m)
36  
        , m_(m)
37  
    {
37  
    {
38  
    }
38  
    }
39  

39  

40  
    auto
40  
    auto
41  
    parse(
41  
    parse(
42  
        char const*& it,
42  
        char const*& it,
43  
        char const* end) const ->
43  
        char const* end) const ->
44  
            system::result<value_type>;
44  
            system::result<value_type>;
45  

45  

46  
private:
46  
private:
47  
    struct first_rule;
47  
    struct first_rule;
48  
    struct next_rule;
48  
    struct next_rule;
49  

49  

50  
    std::size_t n_;
50  
    std::size_t n_;
51  
    std::size_t m_;
51  
    std::size_t m_;
52  
};
52  
};
53  
} // implementation_defined
53  
} // implementation_defined
54  

54  

55  
/** Rule for a comma-delimited list of elements
55  
/** Rule for a comma-delimited list of elements
56  

56  

57  
    This rule defines a list containing
57  
    This rule defines a list containing
58  
    at least n and at most m of Element,
58  
    at least n and at most m of Element,
59  
    each separated by at least one comma
59  
    each separated by at least one comma
60  
    and optional whitespace.
60  
    and optional whitespace.
61  

61  

62  
    @par BNF
62  
    @par BNF
63  
    @code
63  
    @code
64  
    #element       => [ 1#element ]
64  
    #element       => [ 1#element ]
65  
    1#element      => element *( OWS "," OWS element )
65  
    1#element      => element *( OWS "," OWS element )
66  
    <n>#<m>element => element <n-1>*<m-1>( OWS "," OWS element )
66  
    <n>#<m>element => element <n-1>*<m-1>( OWS "," OWS element )
67  
    @endcode
67  
    @endcode
68  

68  

69  
    Senders must emit compliant values, but
69  
    Senders must emit compliant values, but
70  
    receivers should accept values generated
70  
    receivers should accept values generated
71  
    with the legacy production rules:
71  
    with the legacy production rules:
72  

72  

73  
    @par Legacy BNF
73  
    @par Legacy BNF
74  
    @code
74  
    @code
75  
    #element    => [ ( "," / element ) *( OWS "," [ OWS element ] ) ]
75  
    #element    => [ ( "," / element ) *( OWS "," [ OWS element ] ) ]
76  

76  

77  
    1#element   => *( "," OWS ) element *( OWS "," [ OWS element ] )
77  
    1#element   => *( "," OWS ) element *( OWS "," [ OWS element ] )
78  
    @endcode
78  
    @endcode
79  

79  

80  
    @tparam Rule The rule type.
80  
    @tparam Rule The rule type.
81  

81  

82  
    @param r The rule to use for elements.
82  
    @param r The rule to use for elements.
83  
    @param n The minimum number of elements, which may be zero.
83  
    @param n The minimum number of elements, which may be zero.
84  
    @param m The maximum number of elements.
84  
    @param m The maximum number of elements.
85  

85  

86  
    @return A rule that matches the list.
86  
    @return A rule that matches the list.
87  

87  

88  
    @par Specification
88  
    @par Specification
89  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-7"
89  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-7"
90  
        >5.6.1. Lists (#rule ABNF Extension) (rfc7230)</a>
90  
        >5.6.1. Lists (#rule ABNF Extension) (rfc7230)</a>
91  
*/
91  
*/
92  
template<class Rule>
92  
template<class Rule>
93  
constexpr
93  
constexpr
94  
auto
94  
auto
95  
list_rule(
95  
list_rule(
96  
    Rule const& r,
96  
    Rule const& r,
97  
    std::size_t n = 0,
97  
    std::size_t n = 0,
98  
    std::size_t m =
98  
    std::size_t m =
99  
        std::size_t(-1)) noexcept ->
99  
        std::size_t(-1)) noexcept ->
100  
    implementation_defined::list_rule_t<Rule>
100  
    implementation_defined::list_rule_t<Rule>
101  
{
101  
{
102  
    return implementation_defined::list_rule_t<Rule>(r, n, m);
102  
    return implementation_defined::list_rule_t<Rule>(r, n, m);
103  
}
103  
}
104  

104  

105  
} // http
105  
} // http
106  
} // boost
106  
} // boost
107  

107  

108  
#include <boost/http/rfc/impl/list_rule.hpp>
108  
#include <boost/http/rfc/impl/list_rule.hpp>
109  

109  

110  
#endif
110  
#endif