2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-20 05:02:43 +00:00
Files
url/test/unit/doc_grammar.cpp
alandefreitas ce31dfd4d2 docs: format tables for new UI
This commit formats tables so that the content fits in the margins of the new UI template.
2023-11-09 16:21:06 -03:00

346 lines
9.4 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/url
//
#include <boost/url.hpp>
#include "test_suite.hpp"
#include <boost/core/ignore_unused.hpp>
#include <iostream>
namespace boost {
namespace urls {
namespace grammar {
namespace impl {
//[code_grammar_1_1
template< class Rule >
auto parse( core::string_view s, Rule const& r) -> system::result< typename Rule::value_type >;
template< class Rule >
auto parse( char const *& it, char const* end, Rule const& r) -> system::result< typename Rule::value_type >;
//]
} // impl
//------------------------------------------------
namespace {
//[code_grammar_2_2
struct ws_chars_t
{
constexpr bool operator()( char c ) const noexcept
{
return c == '\t' || c == ' ' || c == '\r' || c == '\n';
}
};
//]
//[code_grammar_2_3
static_assert( is_charset< ws_chars_t >::value, "CharSet requirements not met" );
//]
//[code_grammar_2_4
constexpr ws_chars_t ws_chars{};
//]
//[code_grammar_2_5
core::string_view get_token( core::string_view s ) noexcept
{
auto it0 = s.data();
auto const end = it0 + s.size();
// find the first non-whitespace character
it0 = find_if_not( it0, end, ws_chars );
if( it0 == end )
{
// all whitespace or empty string
return {};
}
// find the next whitespace character
auto it1 = find_if( it0, end, ws_chars );
// [it0, it1) is the part we want
return core::string_view( it0, it1 - it0 );
}
//]
//[code_grammar_2_9
struct is_visible
{
constexpr bool operator()( char ch ) const noexcept
{
return ch >= 33 && ch <= 126;
}
};
constexpr lut_chars visible_chars( is_visible{} ); // (since C++11)
//]
#if __cplusplus >= 201703L
namespace cpp17 {
//[code_grammar_2_10
constexpr lut_chars visible_chars( [](char ch) { return ch >= 33 && ch <= 126; } ); // (since C++17)
//]
} // cpp17
#endif
} // (anon)
struct doc_grammar_test
{
void snippets1()
{
//[code_grammar_1_2
struct comma_rule_t
{
// The type of value returned upon success
using value_type = core::string_view;
// The algorithm which checks for a match
system::result< value_type >
parse( char const*& it, char const* end ) const
{
if( it != end && *it == ',')
return core::string_view( it++, 1 );
return error::mismatch;
}
};
//]
//[code_grammar_1_3
constexpr comma_rule_t comma_rule{};
//]
{
//[code_grammar_1_4
system::result< core::string_view > rv = parse( ",", comma_rule );
assert( rv.has_value() && rv.value() == "," );
//]
}
{
//[code_grammar_1_5
system::result< unsigned short > rv =
parse( "16384", unsigned_rule< unsigned short >{} );
//]
ignore_unused(rv);
}
{
//[code_grammar_1_6
system::result< core::string_view > rv = parse( ",", delim_rule(',') );
//]
ignore_unused(rv);
}
}
//--------------------------------------------
void snippets2()
{
{
//[code_grammar_2_6
assert( get_token( " \t john-doe\r\n \t jane-doe\r\n") == "john-doe" );
//]
}
static
//[code_grammar_2_7
constexpr lut_chars vowels = "AEIOU" "aeiou";
//]
{
//[code_grammar_2_8
constexpr auto vowels_and_y = vowels + 'y' + 'Y';
//]
ignore_unused(vowels_and_y);
}
{
//[code_grammar_2_11
constexpr auto visible_non_vowels = visible_chars - vowels;
//]
ignore_unused(visible_non_vowels);
}
{
//[code_grammar_2_12
constexpr auto visible_non_vowels_or_y = visible_chars - vowels - 'y';
//]
ignore_unused(visible_non_vowels_or_y);
}
}
//--------------------------------------------
void snippets3()
{
{
//[code_grammar_3_1
constexpr auto version_rule = tuple_rule( delim_rule( 'v' ), dec_octet_rule, delim_rule( '.' ), dec_octet_rule );
//]
//[code_grammar_3_2
system::result< std::tuple< core::string_view, unsigned char, core::string_view, unsigned char > > rv = parse( "v42.44800", version_rule );
//]
ignore_unused(rv);
}
{
//[code_grammar_3_3
constexpr auto version_rule = tuple_rule( squelch( delim_rule( 'v' ) ), dec_octet_rule, squelch( delim_rule( '.' ) ), dec_octet_rule );
system::result< std::tuple< unsigned char, unsigned char > > rv = parse( "v42.44800", version_rule );
//]
ignore_unused(rv);
}
{
//[code_grammar_3_4
// port = ":" unsigned-short
constexpr auto port_rule = tuple_rule( squelch( delim_rule( ':' ) ), unsigned_rule< unsigned short >{} );
system::result< unsigned short > rv = parse( ":443", port_rule );
//]
ignore_unused(rv);
}
{
//[code_grammar_3_5
// port = [ ":" unsigned-short ]
constexpr auto port_rule = optional_rule( tuple_rule( squelch( delim_rule( ':' ) ), unsigned_rule< unsigned short >{} ) );
system::result< boost::optional< unsigned short > > rv = parse( ":8080", port_rule );
assert( rv->has_value() && rv->value() == 8080 );
//]
}
{
//[code_grammar_3_6
// ipv4_address = dec-octet "." dec-octet "." dec-octet "." dec-octet
//
// port = ":" unsigned-short
//
// endpoint = ipv4_address [ port ]
constexpr auto endpoint_rule = tuple_rule(
tuple_rule(
dec_octet_rule, squelch( delim_rule( '.' ) ),
dec_octet_rule, squelch( delim_rule( '.' ) ),
dec_octet_rule, squelch( delim_rule( '.' ) ),
dec_octet_rule ),
optional_rule(
tuple_rule(
squelch( delim_rule( ':' ) ),
unsigned_rule< unsigned short >{} ) ) );
//]
ignore_unused(endpoint_rule);
}
{
//[code_grammar_3_7
constexpr auto endpoint_rule = tuple_rule(
ipv4_address_rule,
optional_rule(
tuple_rule(
squelch( delim_rule( ':' ) ),
unsigned_rule< unsigned short >{} ) ) );
system::result< std::tuple< ipv4_address, boost::optional< unsigned short > > > rv = parse( "192.168.0.1:443", endpoint_rule );
//]
ignore_unused(rv);
}
{
//[code_grammar_3_8
constexpr auto request_target_rule = variant_rule(
origin_form_rule,
absolute_uri_rule,
authority_rule,
delim_rule('*') );
system::result< variant2::variant< url_view, url_view, authority_view, core::string_view > > rv = parse( "/results.htm?page=4", request_target_rule );
//]
}
}
void snippets4()
{
{
//[code_grammar_4_1
constexpr auto chunk_ext_rule = range_rule(
tuple_rule( squelch( delim_rule( ';' ) ), token_rule( alnum_chars ) ) );
//]
//[code_grammar_4_2
system::result< range< core::string_view > > rv = parse( ";johndoe;janedoe;end", chunk_ext_rule );
for( auto s : rv.value() )
std::cout << s << "\n";
//]
}
{
//[code_grammar_4_3
constexpr auto token_list_rule = range_rule(
token_rule( alnum_chars ),
tuple_rule( squelch( delim_rule( ',' ) ), token_rule( alnum_chars ) ),
1 );
//]
//[code_grammar_4_4
system::result< range< core::string_view > > rv = parse( "johndoe,janedoe,end", token_list_rule );
for( auto s : rv.value() )
std::cout << s << "\n";
//]
}
}
void
snippets5()
{
{
core::string_view s;
//[code_grammar_5_1
system::result< pct_string_view > rv = parse( s, pct_encoded_rule( pchars ) );
//]
ignore_unused(rv);
}
{
//[code_grammar_5_2
// request-line = method SP request-target SP HTTP-version CRLF
constexpr auto request_line_rule = tuple_rule(
not_empty_rule( token_rule( alpha_chars ) ), // method
squelch( delim_rule( ' ' ) ), // SP
variant_rule(
absolute_uri_rule, // absolute-uri or
relative_ref_rule), // relative-ref
squelch( delim_rule( ' ' ) ),
squelch( literal_rule( "HTTP/" ) ), // "HTTP/"
delim_rule( digit_chars ), // DIGIT
squelch( delim_rule( '.' ) ), // "."
delim_rule( digit_chars ), // DIGIT
squelch( literal_rule( "\r\n" ) ) ); // CRLF
//]
ignore_unused(request_line_rule);
}
}
void
run()
{
snippets1();
snippets2();
snippets3();
snippets4();
}
};
TEST_SUITE(
doc_grammar_test,
"boost.url.doc.grammar");
} // grammar
} // urls
} // boost