@@ -7,6 +7,7 @@ use std::collections::HashMap;
77#[ derive( Debug , Clone ) ]
88pub struct MethodMatcher < T : RouteData > {
99 methods : HashMap < String , Box < dyn RequestMatcher < T > > > ,
10+ exclude_methods : HashMap < Vec < String > , Box < dyn RequestMatcher < T > > > ,
1011 any_method : Box < dyn RequestMatcher < T > > ,
1112 count : usize ,
1213}
@@ -21,6 +22,14 @@ impl<T: RouteData> RequestMatcher<T> for MethodMatcher<T> {
2122 if methods. is_empty ( ) {
2223 self . any_method . insert ( route) ;
2324 } else {
25+ if route. exclude_methods ( ) . is_some ( ) {
26+ self . exclude_methods
27+ . entry ( methods. clone ( ) )
28+ . or_insert_with ( || MethodMatcher :: create_sub_matcher ( ) )
29+ . insert ( route. clone ( ) ) ;
30+
31+ return ;
32+ }
2433 for method in methods {
2534 if !self . methods . contains_key ( method) {
2635 self . methods . insert ( method. to_string ( ) , MethodMatcher :: create_sub_matcher ( ) ) ;
@@ -48,6 +57,12 @@ impl<T: RouteData> RequestMatcher<T> for MethodMatcher<T> {
4857 matcher. len ( ) > 0
4958 } ) ;
5059
60+ self . exclude_methods . retain ( |_, matcher| {
61+ removed = removed || matcher. remove ( id) ;
62+
63+ matcher. len ( ) > 0
64+ } ) ;
65+
5166 if removed {
5267 self . count -= 1 ;
5368 }
@@ -62,13 +77,47 @@ impl<T: RouteData> RequestMatcher<T> for MethodMatcher<T> {
6277 routes. extend ( matcher. match_request ( request) ) ;
6378 }
6479
80+ for ( methods, matcher) in & self . exclude_methods {
81+ if !methods. contains ( & request. method ( ) . into ( ) ) {
82+ routes. extend ( matcher. match_request ( request) ) ;
83+ }
84+ }
85+
6586 routes
6687 }
6788
6889 fn trace ( & self , request : & Request ) -> Vec < Trace < T > > {
6990 let mut traces = self . any_method . trace ( request) ;
7091 let request_method = request. method ( ) ;
7192
93+ for ( methods, matcher) in & self . exclude_methods {
94+ if !methods. contains ( & request_method. into ( ) ) {
95+ let method_traces = matcher. trace ( request) ;
96+
97+ traces. push ( Trace :: new (
98+ true ,
99+ true ,
100+ matcher. len ( ) as u64 ,
101+ method_traces,
102+ TraceInfo :: ExcludeMethods {
103+ request : request_method. to_string ( ) ,
104+ against : Some ( methods. clone ( ) ) ,
105+ } ,
106+ ) ) ;
107+ } else {
108+ traces. push ( Trace :: new (
109+ false ,
110+ false ,
111+ matcher. len ( ) as u64 ,
112+ Vec :: new ( ) ,
113+ TraceInfo :: ExcludeMethods {
114+ request : request_method. to_string ( ) ,
115+ against : Some ( methods. clone ( ) ) ,
116+ } ,
117+ ) ) ;
118+ }
119+ }
120+
72121 for ( method, matcher) in & self . methods {
73122 if method == request_method {
74123 let method_traces = matcher. trace ( request) ;
@@ -140,6 +189,7 @@ impl<T: RouteData> Default for MethodMatcher<T> {
140189 fn default ( ) -> Self {
141190 MethodMatcher {
142191 methods : HashMap :: new ( ) ,
192+ exclude_methods : HashMap :: new ( ) ,
143193 any_method : MethodMatcher :: create_sub_matcher ( ) ,
144194 count : 0 ,
145195 }
0 commit comments