RESTinio
path2regex.hpp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
10 #pragma once
11 
12 #include <cassert>
13 #include <regex>
14 #include <string>
15 #include <vector>
16 #include <memory>
17 #include <functional>
18 #include <iterator>
19 
21 
22 #include <restinio/exception.hpp>
23 #include <restinio/string_view.hpp>
24 
25 namespace restinio
26 {
27 
28 namespace path2regex
29 {
30 
31 namespace impl
32 {
33 
34 //
35 // escape_group()
36 //
37 
39 inline auto
40 escape_group( const std::string & group )
41 {
42  std::string result;
43  result.reserve( group.size() + group.size() / 2 );
44 
45  for( const char c : group )
46  {
47  if( '=' == c || '!' == c || ':' == c ||
48  '$' == c || '/' == c || '(' == c || ')' == c )
49  result+= '\\';
50 
51  result+= c;
52  }
53 
54  return result;
55 }
56 
57 //
58 // escape_string()
59 //
60 
62 inline auto
63 escape_string( const std::string & group )
64 {
65  std::string result;
66  result.reserve( group.size() + group.size() / 2 );
67 
68  for( const char c : group )
69  {
70  if( '.' == c || '+' == c || '*' == c ||
71  '?' == c || '=' == c || '^' == c ||
72  ':' == c || '$' == c || '{' == c ||
73  '}' == c || '(' == c || ')' == c ||
74  '[' == c || ']' == c || '|' == c ||
75  '\\' == c || '/' == c )
76  result+= '\\';
77 
78  result+= c;
79  }
80 
81  return result;
82 }
83 
84 } /* namespace impl */
85 
86 //
87 // options_t
88 //
89 
91 class options_t
92 {
93  public:
94  options_t &
95  sensitive( bool s ) &
96  {
97  m_sensitive = s;
98  return *this;
99  }
100 
101  options_t &&
102  sensitive( bool s ) &&
103  {
104  return std::move( this->sensitive( s ) );
105  }
106 
107  bool
108  sensitive() const
109  {
110  return m_sensitive;
111  }
112 
113  options_t &
114  strict( bool p ) &
115  {
116  m_strict = p;
117  return *this;
118  }
119 
120  options_t &&
121  strict( bool p ) &&
122  {
123  return std::move( this->strict( p ) );
124  }
125 
126  bool
127  strict() const
128  {
129  return m_strict;
130  }
131 
132  options_t &
133  ending( bool p ) &
134  {
135  m_ending = p;
136  return *this;
137  }
138 
139  options_t &&
140  ending( bool p ) &&
141  {
142  return std::move( this->ending( p ) );
143  }
144 
145  bool
146  ending() const
147  {
148  return m_ending;
149  }
150 
151  options_t &
152  delimiter( std::string p ) &
153  {
154  m_delimiter = std::move( p );
155  return *this;
156  }
157 
158  options_t &&
159  delimiter( std::string p ) &&
160  {
161  return std::move( this->delimiter( std::move( p ) ) );
162  }
163 
164  const std::string &
165  delimiter() const
166  {
167  return m_delimiter;
168  }
169 
170  std::string
171  make_delimiter( std::string d ) const
172  {
173  std::string result{ std::move( d ) };
174 
175  if( result.empty() )
176  result = delimiter();
177 
178  return result;
179  }
180 
181  options_t &
182  delimiters( std::string p ) &
183  {
184  m_delimiters = std::move( p );
185  return *this;
186  }
187 
188  options_t &&
189  delimiters( std::string p ) &&
190  {
191  return std::move( this->delimiters( std::move( p ) ) );
192  }
193 
194  const std::string &
195  delimiters() const
196  {
197  return m_delimiters;
198  }
199 
200  options_t &
201  ends_with( std::vector< std::string > p ) &
202  {
203  m_ends_with = std::move( p );
204  return *this;
205  }
206 
207  options_t &&
208  ends_with( std::vector< std::string > p ) &&
209  {
210  return std::move( this->ends_with( std::move( p ) ) );
211  }
212 
213  const std::vector< std::string > &
214  ends_with() const
215  {
216  return m_ends_with;
217  }
218 
219  std::string
221  {
222  std::string result;
223 
224  for( const auto & e : m_ends_with )
225  {
226  if( !e.empty() )
227  {
228  result += impl::escape_string( e ) + "|";
229  }
230  }
231 
232  result += "$";
233 
234  return result;
235  }
236 
237  private:
239  bool m_sensitive{ false };
240 
242  bool m_strict{ false };
243 
245  bool m_ending{ true };
246 
248  std::string m_delimiter{ "/" };
249 
251  std::string m_delimiters{ "./" };
252 
254  std::vector< std::string > m_ends_with;
255 };
256 
257 //
258 // param_appender_t
259 //
260 
262 template < typename Route_Param_Appender >
264  std::function< void ( Route_Param_Appender &, string_view_t ) >;
265 
266 //
267 // param_appender_sequence_t
268 //
269 
271 template < typename Route_Param_Appender >
272 using param_appender_sequence_t = std::vector< param_appender_t< Route_Param_Appender > >;
273 
274 //
275 // make_param_setter
276 //
277 
279 template < typename Route_Param_Appender >
282 {
283  return
284  [ key ](
285  Route_Param_Appender & parameters,
286  string_view_t value ){
287  parameters.add_named_param( key, value );
288  };
289 }
290 
292 template < typename Route_Param_Appender >
293 inline param_appender_t< Route_Param_Appender >
294 make_param_setter( std::size_t )
295 {
296  return
297  []( Route_Param_Appender & parameters, string_view_t value ){
298  parameters.add_indexed_param( value );
299  };
300 }
301 
302 namespace impl
303 {
304 
305 //
306 // string_view_buffer_storage_appender_t
307 //
308 
310 template < typename Container >
312 {
313  public:
314  string_view_buffer_storage_appender_t( std::size_t reserve_size, Container & buffer )
315  : m_buffer{ buffer }
316  {
317  m_buffer.reserve( reserve_size );
318  assert( m_buffer.capacity() >= reserve_size );
319  }
320 
324  append_name( const std::string & name )
325  {
326  const auto n = name.size();
327  if( m_buffer.capacity() - m_buffer.size() < n )
328  {
329  // This actually should never happen,
330  // because buffer is set to the size
331  // of a whole route-path that itself contains all the names.
332  throw exception_t{ "unable to insert data into names buffer" };
333  }
334 
335  // Remember where previous names finishes.
336  const auto prev_size = m_buffer.size();
337 
338  std::copy( name.data(), name.data() + n, std::back_inserter( m_buffer ) );
339  return string_view_t{ m_buffer.data() + prev_size, n };
340  }
341 
343  std::size_t
344  append_name( std::size_t i ) const
345  {
346  return i;
347  }
348 
349  private:
350  Container & m_buffer;
351 };
352 
354 
356 constexpr auto path_regex_str =
357  R"((\\.)|(?:\:(\w+)(?:\‍(((?:\\.|[^\\‍()])+)\))?|\‍(((?:\\.|[^\\‍()])+)\))([+*?])?)";
358 
359 enum class token_type_t : std::uint8_t
360 {
361  plain_string,
363 };
364 
365 //
366 // token_t
367 //
368 
370 template < typename Route_Param_Appender >
371 class token_t
372 {
373  public:
374  token_t() = default;
375  token_t( const token_t & ) = delete;
376  token_t( token_t && ) = delete;
377  virtual ~token_t() = default;
378 
379  virtual token_type_t
381  std::string & route,
382  param_appender_sequence_t< Route_Param_Appender > & param_appender_sequence,
383  names_buffer_appender_t & names_buffer_appender ) const = 0;
384 
385  virtual bool
386  is_end_delimited( const std::string & ) const noexcept
387  {
388  return false;
389  }
390 };
391 
392 template < typename Route_Param_Appender >
393 using token_unique_ptr_t = std::unique_ptr< token_t< Route_Param_Appender > >;
394 
395 template < typename Route_Param_Appender >
396 using token_list_t = std::vector< token_unique_ptr_t< Route_Param_Appender > >;
397 
398 //
399 // plain_string_token_t
400 //
401 
403 template < typename Route_Param_Appender >
404 class plain_string_token_t final : public token_t< Route_Param_Appender >
405 {
406  public:
407  plain_string_token_t( const std::string & path )
408  : m_escaped_path{ escape_string( path ) }
409  , m_last_char{ path.back() }
410  {}
411 
412  virtual token_type_t
414  std::string & route,
416  names_buffer_appender_t & ) const override
417  {
418  route += m_escaped_path;
419 
420  return token_type_t::plain_string;
421  }
422 
423  virtual bool
424  is_end_delimited( const std::string & delimiters ) const noexcept override
425  {
426  return std::string::npos != delimiters.find( m_last_char );
427  }
428 
429  private:
431  const std::string m_escaped_path;
432  const char m_last_char;
433 };
434 
435 template < typename Route_Param_Appender >
437 create_token( std::string path )
438 {
440  return std::make_unique< token_t >( std::move( path ) );
441 }
442 
443 //
444 // parameter_token_t
445 //
446 
448 template < typename Route_Param_Appender, typename Name >
449 class parameter_token_t final : public token_t< Route_Param_Appender >
450 {
451  public:
454 
456  Name name,
457  const std::string & prefix,
458  std::string delimiter,
459  bool optional,
460  bool repeat,
461  bool partial,
462  std::string pattern )
463  : m_name{ std::move( name ) }
464  , m_escaped_prefix{ escape_string( prefix ) }
465  , m_delimiter{ std::move( delimiter ) }
466  , m_optional{ optional }
467  , m_repeat{ repeat }
468  , m_partial{ partial }
469  , m_pattern{ std::move( pattern ) }
470  {}
471 
472  virtual token_type_t
474  std::string & route,
475  param_appender_sequence_t< Route_Param_Appender > & param_appender_sequence,
476  names_buffer_appender_t & names_buffer_appender ) const override
477  {
478  // Basic capturing pattern.
479  auto capture = "(?:" + m_pattern + ")";
480 
481  if( m_repeat )
482  {
483  // Add * as the parameter can be repeeated.
484  capture += "(?:" + m_escaped_prefix + capture + ")*";
485  }
486 
487  if( m_optional )
488  {
489  // Optional param goes in ()?.
490  if( !m_partial )
491  {
492  capture = "(?:" + m_escaped_prefix + "(" + capture + "))?";
493  }
494  else
495  {
496  capture = m_escaped_prefix + "(" + capture + ")?";
497  }
498  }
499  else
500  {
501  // Mandatory param goes in ().
502  capture = m_escaped_prefix + "(" + capture + ")";
503  }
504 
505  route += capture;
506 
507  param_appender_sequence.push_back(
508  make_param_setter< Route_Param_Appender >(
509  names_buffer_appender.append_name( m_name ) ) );
510 
512  }
513 
514  private:
515  const Name m_name;
516  const std::string m_escaped_prefix;
517  const std::string m_delimiter;
518  const bool m_optional;
519  const bool m_repeat;
520  const bool m_partial;
521  const std::string m_pattern;
522 };
523 
524 //
525 // create_token()
526 //
527 
529 template < typename Route_Param_Appender, typename Name >
532  Name name,
533  std::string prefix,
534  std::string delimiter,
535  bool optional,
536  bool repeat,
537  bool partial,
538  std::string pattern )
539 {
540  return std::make_unique< parameter_token_t< Route_Param_Appender, Name > >(
541  std::move( name ),
542  std::move( prefix ),
543  std::move( delimiter ),
544  optional,
545  repeat,
546  partial,
547  std::move( pattern ) );
548 }
549 
553 constexpr std::size_t group_escaped_idx = 1;
554 constexpr std::size_t group_name_idx = 2;
555 constexpr std::size_t group_capture_idx = 3;
556 constexpr std::size_t group_group_idx = 4;
557 constexpr std::size_t group_modifier_idx = 5;
559 
561 inline std::string
562 check_no_unescaped_brackets( string_view_t strv, std::size_t base_pos )
563 {
564  auto pos = strv.find( '(' );
565  if( std::string::npos != pos )
566  {
567  throw exception_t{
568  fmt::format(
569  "non-escaped bracket '(' at pos {}: may be unmatched group start",
570  base_pos + pos ) };
571  }
572 
573  pos = strv.find( ')' );
574  if( std::string::npos != pos )
575  {
576  throw exception_t{
577  fmt::format(
578  "non-escaped bracket ')' at pos {}: may be unmatched group finish",
579  base_pos + pos ) };
580  }
581 
582  return std::string{ strv.data(), strv.size() };
583 }
584 
585 //
586 // handle_param_token()
587 //
588 
590 template < typename Route_Param_Appender, typename MATCH >
591 inline void
593  const options_t & options,
594  const MATCH & match,
595  std::string & path,
596  bool & path_escaped,
598 {
599  std::string prefix{ "" }; // prev in js code.
600  if( !path_escaped && !path.empty() )
601  {
602  const auto k = path.size() - 1;
603 
604  if( std::string::npos != options.delimiters().find( path[k] ) )
605  {
606  prefix = path.substr( k, 1 );
607  path = path.substr( 0, k );
608  }
609  }
610 
611  // Push the current path onto the tokens.
612  if( !path.empty() )
613  {
614  result.push_back( create_token< Route_Param_Appender >( std::move( path ) ) );
615  path_escaped = false;
616  }
617 
618  const auto next = match.suffix().str().substr( 0, 1 );
619 
620  std::string name{ match[ group_name_idx ].str() };
621  const std::string modifier{ match[ group_modifier_idx ].str() };
622 
623  const bool partial = !prefix.empty() && !next.empty() && prefix != next;
624 
625  const bool optional = modifier == "?" || modifier == "*";
626  const bool repeat = modifier == "+" || modifier == "*";
627  std::string delimiter = options.make_delimiter( prefix );
628 
629  auto create_pattern = [ delimiter ]( auto pattern ){
630  if( !pattern.empty() )
631  {
632  pattern = escape_group( pattern );
633  }
634  else
635  {
636  pattern = "[^" + escape_string( delimiter ) + "]+?";
637  }
638  return pattern;
639  };
640 
641  if( !name.empty() )
642  {
643  // Named parameter.
644  result.push_back(
645  create_token< Route_Param_Appender >(
646  name,
647  std::move( prefix ),
648  std::move( delimiter ),
649  optional,
650  repeat,
651  partial,
652  create_pattern( match[ group_capture_idx ].str() ) ) );
653  }
654  else
655  {
656  // Indexed parameter.
657  result.push_back(
658  create_token< Route_Param_Appender >(
659  std::size_t{ 0 }, // just to have a variable of this type.
660  std::move( prefix ),
661  std::move( delimiter ),
662  optional,
663  repeat,
664  partial,
665  create_pattern( match[ group_group_idx ].str() ) ) );
666  }
667 }
668 
669 //
670 // parse()
671 //
672 
674 template < typename Route_Param_Appender >
675 token_list_t< Route_Param_Appender >
676 parse( string_view_t route_sv, const options_t & options )
677 {
679 
680  std::string path{};
681  const std::regex main_path_regex{ path_regex_str };
682  bool path_escaped = false;
683 
684  std::cregex_iterator token_it{
685  route_sv.data(),
686  route_sv.data() + route_sv.size(),
687  main_path_regex
688  };
689  std::cregex_iterator token_end{};
690 
691  if( token_it == token_end )
692  {
693  // Path is a single token.
694  path = check_no_unescaped_brackets( route_sv, 0 );
695  }
696 
697  while( token_it != token_end )
698  {
699  const auto & match = *token_it;
700 
701  assert( 6 == match.size() );
702 
703  const string_view_t prefix{
704  match.prefix().first,
705  static_cast<std::size_t>( match.prefix().length() ) };
706 
707  path += check_no_unescaped_brackets( prefix,
708  static_cast<std::size_t>(match.position()) - prefix.size() );
709 
710  const auto escaped = match[ group_escaped_idx ].str();
711  if( !escaped.empty() )
712  {
713  assert( 2 == escaped.size() );
714  path += escaped[ 1 ];
715  path_escaped = true;
716  }
717  else
718  {
719  handle_param_token( options, match, path, path_escaped, result );
720  }
721 
722  auto next_it = token_it;
723  std::advance( next_it, 1 );
724 
725  if( next_it == token_end )
726  {
727  const std::string suffix{ match.suffix() };
728  path +=
730  suffix,
731  static_cast<std::size_t>(match.position() + match.length()) );
732  }
733 
734  token_it = next_it;
735  }
736 
737  if( !path.empty() )
738  result.push_back( create_token< Route_Param_Appender >( std::move( path ) ) );
739 
740  return result;
741 }
742 
743 //
744 // route_regex_matcher_data_t
745 //
746 
748 template < typename Route_Param_Appender, typename Regex_Engine >
750 {
754 
757 
758  using regex_t = typename Regex_Engine::compiled_regex_t;
759 
761 
763 
767  std::shared_ptr< std::string > m_named_params_buffer;
768 
771 };
772 
773 //
774 // tokens2regexp()
775 //
776 
778 template < typename Route_Param_Appender, typename Regex_Engine >
779 auto
781  string_view_t path,
783  const options_t & options )
784 {
786  try
787  {
788  result.m_named_params_buffer = std::make_shared< std::string >();
790  names_buffer_appender{ path.size(), *result.m_named_params_buffer };
791 
792  std::string route;
793  auto & param_appender_sequence = result.m_param_appender_sequence;
794 
795  // The number of capture groups in resultin regex
796  // 1 is for match of a route itself.
797  std::size_t captured_groups_count = 1 ;
798 
799  for( const auto & t : tokens )
800  {
801  const auto appended_token_type =
802  t->append_self_to( route, param_appender_sequence, names_buffer_appender );
803 
804  if( token_type_t::capturing_token == appended_token_type )
805  ++captured_groups_count;
806  }
807 
808  if( Regex_Engine::max_capture_groups() < captured_groups_count )
809  {
810  // This number of captures is not possible with this engine.
811  throw exception_t{
812  fmt::format(
813  "too many parameter to capture from route: {}, while {} is the maximum",
814  captured_groups_count,
815  Regex_Engine::max_capture_groups() ) };
816  }
817 
818  const auto & delimiter = escape_string( options.delimiter() );
819  const auto & ends_with = options.make_ends_with();
820 
821  if( options.ending() )
822  {
823  if( !options.strict() )
824  {
825  route += "(?:" + delimiter + ")?";
826  }
827 
828  if( ends_with == "$" )
829  route += '$';
830  else
831  route += "(?=" + ends_with + ")";
832  }
833  else
834  {
835  if( !options.strict() )
836  route += "(?:" + delimiter + "(?=" + ends_with + "))?";
837 
838  if( !tokens.empty() &&
839  !tokens.back()->is_end_delimited( options.delimiters() ) )
840  route += "(?=" + delimiter + "|" + ends_with + ")";
841  }
842 
843  result.m_regex = Regex_Engine::compile_regex( "^" + route, options.sensitive() );
844  }
845  catch( const std::exception & ex )
846  {
847  throw exception_t{
848  fmt::format( "unable to process route \"{}\": {}", path, ex.what() ) };
849  }
850 
851  return result;
852 }
853 
854 } /* namespace impl */
855 
856 //
857 // path2regex()
858 //
859 
861 template < typename Route_Param_Appender, typename Regex_Engine >
862 inline auto
864  string_view_t path,
865  const options_t & options )
866 {
867  return impl::tokens2regexp< Route_Param_Appender, Regex_Engine >(
868  path,
869  impl::parse< Route_Param_Appender >( path, options ),
870  options );
871 }
872 
873 } /* namespace path2regex */
874 
875 } /* namespace restinio */
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::path2regex::impl::plain_string_token_t::is_end_delimited
virtual bool is_end_delimited(const std::string &delimiters) const noexcept override
Definition: path2regex.hpp:424
restinio::path2regex::impl::parameter_token_t::parameter_token_t
parameter_token_t(Name name, const std::string &prefix, std::string delimiter, bool optional, bool repeat, bool partial, std::string pattern)
Definition: path2regex.hpp:455
restinio::path2regex::impl::string_view_buffer_storage_appender_t::append_name
std::size_t append_name(std::size_t i) const
A stub for indexed paramaters.
Definition: path2regex.hpp:344
restinio::path2regex::impl::parameter_token_t::append_self_to
virtual token_type_t append_self_to(std::string &route, param_appender_sequence_t< Route_Param_Appender > &param_appender_sequence, names_buffer_appender_t &names_buffer_appender) const override
Definition: path2regex.hpp:473
restinio::path2regex::impl::token_t::token_t
token_t(const token_t &)=delete
restinio::path2regex::impl::plain_string_token_t
Plain str token.
Definition: path2regex.hpp:405
restinio::path2regex::impl::parameter_token_t::parameter_token_t
parameter_token_t(parameter_token_t &&)=delete
restinio::path2regex::impl::string_view_buffer_storage_appender_t::m_buffer
Container & m_buffer
Definition: path2regex.hpp:350
restinio::path2regex::impl::token_t::token_t
token_t()=default
restinio::path2regex::options_t::delimiters
options_t & delimiters(std::string p) &
Definition: path2regex.hpp:182
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
restinio::path2regex::impl::route_regex_matcher_data_t::m_regex
regex_t m_regex
Definition: path2regex.hpp:760
restinio::path2regex::options_t::sensitive
options_t && sensitive(bool s) &&
Definition: path2regex.hpp:102
restinio::path2regex::impl::route_regex_matcher_data_t::route_regex_matcher_data_t
route_regex_matcher_data_t(route_regex_matcher_data_t &&)=default
string_view.hpp
restinio::path2regex::impl::group_capture_idx
constexpr std::size_t group_capture_idx
Definition: path2regex.hpp:555
restinio::path2regex::impl::parse
token_list_t< Route_Param_Appender > parse(string_view_t route_sv, const options_t &options)
Parse a string for the raw tokens.
Definition: path2regex.hpp:676
restinio::path2regex::options_t::delimiters
options_t && delimiters(std::string p) &&
Definition: path2regex.hpp:189
restinio::path2regex::param_appender_sequence_t
std::vector< param_appender_t< Route_Param_Appender > > param_appender_sequence_t
A sequence of appenders for submatches.
Definition: path2regex.hpp:272
restinio::path2regex::impl::string_view_buffer_storage_appender_t::string_view_buffer_storage_appender_t
string_view_buffer_storage_appender_t(std::size_t reserve_size, Container &buffer)
Definition: path2regex.hpp:314
restinio::path2regex::options_t::m_delimiters
std::string m_delimiters
Path delimiters.
Definition: path2regex.hpp:251
restinio::path2regex::options_t::ending
options_t && ending(bool p) &&
Definition: path2regex.hpp:140
restinio::path2regex::options_t
Options for matching routes.
Definition: path2regex.hpp:92
restinio::path2regex::impl::parameter_token_t::m_escaped_prefix
const std::string m_escaped_prefix
Definition: path2regex.hpp:516
restinio::path2regex::impl::token_t::append_self_to
virtual token_type_t append_self_to(std::string &route, param_appender_sequence_t< Route_Param_Appender > &param_appender_sequence, names_buffer_appender_t &names_buffer_appender) const =0
restinio::path2regex::impl::group_group_idx
constexpr std::size_t group_group_idx
Definition: path2regex.hpp:556
restinio::path2regex::impl::parameter_token_t::m_optional
const bool m_optional
Definition: path2regex.hpp:518
restinio::string_view_t
nonstd::string_view string_view_t
Definition: string_view.hpp:19
restinio::path2regex::impl::token_t::is_end_delimited
virtual bool is_end_delimited(const std::string &) const noexcept
Definition: path2regex.hpp:386
restinio::path2regex::impl::group_modifier_idx
constexpr std::size_t group_modifier_idx
Definition: path2regex.hpp:557
restinio::path2regex::impl::escape_string
auto escape_string(const std::string &group)
Excape regex control chars.
Definition: path2regex.hpp:63
restinio::path2regex::impl::parameter_token_t::m_name
const Name m_name
Definition: path2regex.hpp:515
restinio::path2regex::impl::string_view_buffer_storage_appender_t::append_name
string_view_t append_name(const std::string &name)
Appends a given name to buffer, and returns a string view object within the context of a buffer.
Definition: path2regex.hpp:324
restinio::path2regex::impl::token_t::token_t
token_t(token_t &&)=delete
restinio::string_algo::ends_with
RESTINIO_NODISCARD bool ends_with(const string_view_t &where, const string_view_t &what) noexcept
Definition: string_algo.hpp:33
restinio::path2regex::impl::route_regex_matcher_data_t::m_named_params_buffer
std::shared_ptr< std::string > m_named_params_buffer
Char buffer for holding named paramaters.
Definition: path2regex.hpp:767
restinio::path2regex::options_t::m_sensitive
bool m_sensitive
When true the route will be case sensitive.
Definition: path2regex.hpp:239
restinio::path2regex::impl::route_regex_matcher_data_t
Resulting regex and param extraction for a specific route.
Definition: path2regex.hpp:750
restinio::path2regex::options_t::delimiter
options_t && delimiter(std::string p) &&
Definition: path2regex.hpp:159
restinio::path2regex::impl::parameter_token_t::parameter_token_t
parameter_token_t(const parameter_token_t &)=delete
restinio::path2regex::impl::escape_group
auto escape_group(const std::string &group)
Escapes not allowed symbols in a sub-match group assigned to a parameter.
Definition: path2regex.hpp:40
restinio::path2regex::impl::parameter_token_t::m_delimiter
const std::string m_delimiter
Definition: path2regex.hpp:517
restinio::path2regex::impl::route_regex_matcher_data_t::m_param_appender_sequence
param_appender_sequence_t< Route_Param_Appender > m_param_appender_sequence
Appenders for captured values (names/indexed groups).
Definition: path2regex.hpp:770
restinio::path2regex::options_t::make_delimiter
std::string make_delimiter(std::string d) const
Definition: path2regex.hpp:171
restinio::path2regex::impl::route_regex_matcher_data_t::route_regex_matcher_data_t
route_regex_matcher_data_t()=default
restinio::path2regex::options_t::sensitive
bool sensitive() const
Definition: path2regex.hpp:108
restinio::path2regex::options_t::ends_with
options_t & ends_with(std::vector< std::string > p) &
Definition: path2regex.hpp:201
restinio::path2regex::impl::token_t
Base class for token variants.
Definition: path2regex.hpp:372
restinio::path2regex::impl::parameter_token_t::m_repeat
const bool m_repeat
Definition: path2regex.hpp:519
restinio::path2regex::options_t::make_ends_with
std::string make_ends_with() const
Definition: path2regex.hpp:220
MATCH
@ MATCH
Definition: inflate.h:45
restinio::path2regex::options_t::delimiter
const std::string & delimiter() const
Definition: path2regex.hpp:165
restinio::path2regex::impl::parameter_token_t::m_pattern
const std::string m_pattern
Definition: path2regex.hpp:521
restinio::path2regex::options_t::delimiters
const std::string & delimiters() const
Definition: path2regex.hpp:195
restinio::path2regex::impl::route_regex_matcher_data_t::regex_t
typename Regex_Engine::compiled_regex_t regex_t
Definition: path2regex.hpp:758
restinio::path2regex::impl::token_unique_ptr_t
std::unique_ptr< token_t< Route_Param_Appender > > token_unique_ptr_t
Definition: path2regex.hpp:393
include_fmtlib.hpp
A special wrapper around fmtlib include files.
restinio::path2regex::options_t::ends_with
options_t && ends_with(std::vector< std::string > p) &&
Definition: path2regex.hpp:208
restinio::path2regex::impl::plain_string_token_t::append_self_to
virtual token_type_t append_self_to(std::string &route, param_appender_sequence_t< Route_Param_Appender > &, names_buffer_appender_t &) const override
Definition: path2regex.hpp:413
restinio::path2regex::impl::tokens2regexp
auto tokens2regexp(string_view_t path, const token_list_t< Route_Param_Appender > &tokens, const options_t &options)
Makes route regex matcher out of path tokens.
Definition: path2regex.hpp:780
restinio::path2regex::impl::create_token
token_unique_ptr_t< Route_Param_Appender > create_token(std::string path)
Definition: path2regex.hpp:437
restinio::path2regex::impl::token_list_t
std::vector< token_unique_ptr_t< Route_Param_Appender > > token_list_t
Definition: path2regex.hpp:396
restinio::path2regex::impl::group_name_idx
constexpr std::size_t group_name_idx
Definition: path2regex.hpp:554
restinio::path2regex::impl::string_view_buffer_storage_appender_t
Appender for names to a given buffered string.
Definition: path2regex.hpp:312
restinio::path2regex::options_t::m_strict
bool m_strict
When false the trailing slash is optional.
Definition: path2regex.hpp:242
restinio::path2regex::impl::path_regex_str
constexpr auto path_regex_str
The main path matching expression.
Definition: path2regex.hpp:356
restinio
Definition: asio_include.hpp:21
restinio::path2regex::options_t::strict
bool strict() const
Definition: path2regex.hpp:127
restinio::path2regex::impl::plain_string_token_t::plain_string_token_t
plain_string_token_t(const std::string &path)
Definition: path2regex.hpp:407
restinio::path2regex::options_t::delimiter
options_t & delimiter(std::string p) &
Definition: path2regex.hpp:152
restinio::path2regex::param_appender_t
std::function< void(Route_Param_Appender &, string_view_t) > param_appender_t
Appends sub-match as a request parameter to specified container.
Definition: path2regex.hpp:264
exception.hpp
restinio::path2regex::options_t::m_ends_with
std::vector< std::string > m_ends_with
Path delimiter.
Definition: path2regex.hpp:254
restinio::path2regex::impl::token_type_t::plain_string
@ plain_string
restinio::path2regex::options_t::m_delimiter
std::string m_delimiter
Path delimiter.
Definition: path2regex.hpp:248
restinio::path2regex::impl::group_escaped_idx
constexpr std::size_t group_escaped_idx
Indexes for different groups in matched result (used when extracting tokens from initial route).
Definition: path2regex.hpp:553
restinio::path2regex::impl::check_no_unescaped_brackets
std::string check_no_unescaped_brackets(string_view_t strv, std::size_t base_pos)
Checks that string doesn't contain non-excaped brackets.
Definition: path2regex.hpp:562
restinio::path2regex::options_t::strict
options_t && strict(bool p) &&
Definition: path2regex.hpp:121
restinio::path2regex::impl::route_regex_matcher_data_t::operator=
route_regex_matcher_data_t & operator=(const route_regex_matcher_data_t &)=delete
restinio::path2regex::options_t::sensitive
options_t & sensitive(bool s) &
Definition: path2regex.hpp:95
restinio::path2regex::options_t::m_ending
bool m_ending
When false the path will match at the beginning.
Definition: path2regex.hpp:245
restinio::path2regex::impl::plain_string_token_t::m_last_char
const char m_last_char
Definition: path2regex.hpp:432
restinio::path2regex::impl::token_type_t
token_type_t
Definition: path2regex.hpp:360
restinio::path2regex::impl::token_t::~token_t
virtual ~token_t()=default
restinio::path2regex::options_t::ending
bool ending() const
Definition: path2regex.hpp:146
restinio::path2regex::options_t::strict
options_t & strict(bool p) &
Definition: path2regex.hpp:114
restinio::path2regex::options_t::ends_with
const std::vector< std::string > & ends_with() const
Definition: path2regex.hpp:214
restinio::path2regex::impl::parameter_token_t::m_partial
const bool m_partial
Definition: path2regex.hpp:520
restinio::path2regex::impl::handle_param_token
void handle_param_token(const options_t &options, const MATCH &match, std::string &path, bool &path_escaped, token_list_t< Route_Param_Appender > &result)
Handling of a parameterized token.
Definition: path2regex.hpp:592
restinio::path2regex::impl::plain_string_token_t::m_escaped_path
const std::string m_escaped_path
Already escaped piece of the route.
Definition: path2regex.hpp:431
restinio::path2regex::impl::route_regex_matcher_data_t::route_regex_matcher_data_t
route_regex_matcher_data_t(const route_regex_matcher_data_t &)=delete
restinio::path2regex::impl::parameter_token_t
Token for paramater (named/indexed).
Definition: path2regex.hpp:450
restinio::path2regex::options_t::ending
options_t & ending(bool p) &
Definition: path2regex.hpp:133
restinio::easy_parser::repeat
RESTINIO_NODISCARD auto repeat(std::size_t min_occurences, std::size_t max_occurences, Clauses &&... clauses)
A factory function to create repetitor of subclauses.
Definition: easy_parser.hpp:3876
restinio::path2regex::path2regex
auto path2regex(string_view_t path, const options_t &options)
The main path matching regexp.
Definition: path2regex.hpp:863
restinio::path2regex::make_param_setter
param_appender_t< Route_Param_Appender > make_param_setter(string_view_t key)
Create default appender for named parameter.
Definition: path2regex.hpp:281