31#include <boost/system/result.hpp>
32#include <fmt/ostream.h>
64 void set(
const std::string_view name,
const std::string_view value) {
65 parameters_[std::string(name)] = std::string(value);
73 [[nodiscard]]
const std::string*
get(
const std::string_view name)
const {
74 const auto it = parameters_.find(std::string(name));
75 if (it != parameters_.end()) {
89 std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
get_as(
const std::string_view name)
const {
90 const auto it = parameters_.find(std::string(name));
91 if (it != parameters_.end()) {
101 [[nodiscard]]
const std::map<std::string, std::string>&
get_all()
const {
109 return parameters_.empty();
120 std::map<std::string, std::string> parameters_;
133 [[nodiscard]]
static boost::system::result<bool, Error>
134 match(
const std::string_view path,
const std::string_view pattern,
Parameters* parameters =
nullptr) {
135 if (path.empty() || pattern.empty()) {
142 path_parser.
skip(
'/');
143 pattern_parser.
skip(
'/');
145 auto path_section = path_parser.
split(
'/');
146 auto pattern_section = pattern_parser.
split(
'/');
149 if (!path_section && !pattern_section) {
153 if (pattern_section ==
"**") {
160 if (!path_section || !pattern_section) {
164 if (path_section == pattern_section || pattern_section ==
"*") {
165 path_section = path_parser.
split(
'/');
166 pattern_section = pattern_parser.
split(
'/');
171 const auto leading = parameter_parser.
read_until(
'{');
172 const auto parameter_name = parameter_parser.
read_until(
'}');
179 if (!parameter_name || parameter_name->empty()) {
183 auto parameter_value = *path_section;
201 if (parameters ==
nullptr) {
205 parameters->set(*parameter_name, parameter_value);
207 path_section = path_parser.
split(
'/');
208 pattern_section = pattern_parser.
split(
'/');
220struct fmt::formatter<
rav::PathMatcher::Error>: ostream_formatter {};
228 os <<
"invalid_recursive_wildcard";
231 os <<
"invalid_argument";
239 boost::throw_with_location(std::runtime_error(fmt::format(
"PathMatcher::Error: {}", e)), loc);
#define RAV_ASSERT_FALSE(message)
Asserts with false, entering the RAV_ASSERT procedure as a quick way to assert that a branch is inval...
Contains parameters extracted from a path with convenience functions to convert to integers.
void clear()
Clear all parameters.
const std::map< std::string, std::string > & get_all() const
Get all parameters as a map.
const std::string * get(const std::string_view name) const
Get a parameter value by name.
std::enable_if_t< std::is_integral_v< T >, std::optional< T > > get_as(const std::string_view name) const
Get a parameter value by name and convert it to an integer of type T.
void set(const std::string_view name, const std::string_view value)
Set a parameter with the given name and value.
A simple path matcher that matches paths against patterns.
@ invalid_recursive_wildcard
static constexpr auto k_loop_upper_bound
static boost::system::result< bool, Error > match(const std::string_view path, const std::string_view pattern, Parameters *parameters=nullptr)
Match a path against a pattern.
A handy utility class for parsing strings.
std::optional< std::string_view > read_until(const char delimiter, const bool include_delimiter=false)
Reads until given delimiter.
std::optional< std::string_view > read_until_end()
Reads the rest of the string.
std::optional< std::string_view > split(const char delimiter, const bool include_delimiter=false)
Reads until the given delimiter or until the end of the string.
bool skip(const char *chars)
Skips the given sequence of characters from the beginning of the string.
BOOST_NORETURN BOOST_NOINLINE void throw_exception_from_error(PathMatcher::Error const &e, boost::source_location const &loc)
std::enable_if_t< std::is_integral_v< Type >, std::optional< Type > > string_to_int(std::string_view string, const bool strict=false, const int base=10)
String to number - a small convenience function around std::from_chars.
std::string_view string_remove_prefix(const std::string_view &string, const std::string_view prefix_to_remove, bool *found=nullptr)
Returns a copy of string with given prefix removed, if prefix is found at the beginning of the string...
std::string_view string_remove_suffix(const std::string_view &string, const std::string_view suffix_to_remove, bool *found=nullptr)
Returns a copy of string with given suffix removed, if suffix is found at the end of the string.
std::ostream & operator<<(std::ostream &os, const PathMatcher::Error err)