@@ -136,6 +136,29 @@ impl Method {
136136 }
137137 }
138138
139+ /// Convert static bytes into a `Method`.
140+ ///
141+ /// # Panics
142+ ///
143+ /// If the input bytes are not a valid method name or if the method name is over 15 bytes.
144+ pub const fn from_static ( src : & ' static [ u8 ] ) -> Method {
145+ match src {
146+ b"OPTIONS" => Method :: OPTIONS ,
147+ b"GET" => Method :: GET ,
148+ b"POST" => Method :: POST ,
149+ b"PUT" => Method :: PUT ,
150+ b"DELETE" => Method :: DELETE ,
151+ b"HEAD" => Method :: HEAD ,
152+ b"TRACE" => Method :: TRACE ,
153+ b"CONNECT" => Method :: CONNECT ,
154+ b"PATCH" => Method :: PATCH ,
155+ _ => {
156+ let inline = InlineExtension :: from_static ( src) ;
157+ Method ( ExtensionInline ( inline) )
158+ }
159+ }
160+ }
161+
139162 fn extension_inline ( src : & [ u8 ] ) -> Result < Method , InvalidMethod > {
140163 let inline = InlineExtension :: new ( src) ?;
141164
@@ -335,6 +358,34 @@ mod extension {
335358 Ok ( InlineExtension ( data, src. len ( ) as u8 ) )
336359 }
337360
361+ /// Convert static bytes into an `InlineExtension`.
362+ ///
363+ /// # Panics
364+ ///
365+ /// If the input bytes are not a valid method name or if the method name is over 15 bytes.
366+ pub const fn from_static ( src : & ' static [ u8 ] ) -> InlineExtension {
367+ let mut i = 0 ;
368+ let mut dst = [ 0u8 ; 15 ] ;
369+ if src. len ( ) > 15 {
370+ // panicking in const requires Rust 1.57.0
371+ #[ allow( unconditional_panic) ]
372+ ( [ ] as [ u8 ; 0 ] ) [ 0 ] ;
373+ }
374+ while i < src. len ( ) {
375+ let byte = src[ i] ;
376+ let v = METHOD_CHARS [ byte as usize ] ;
377+ if v == 0 {
378+ // panicking in const requires Rust 1.57.0
379+ #[ allow( unconditional_panic) ]
380+ ( [ ] as [ u8 ; 0 ] ) [ 0 ] ;
381+ }
382+ dst[ i] = byte;
383+ i += 1 ;
384+ }
385+
386+ InlineExtension ( dst, i as u8 )
387+ }
388+
338389 pub fn as_str ( & self ) -> & str {
339390 let InlineExtension ( ref data, len) = self ;
340391 // Safety: the invariant of InlineExtension ensures that the first
@@ -440,6 +491,26 @@ mod test {
440491 assert_eq ! ( Method :: GET , & Method :: GET ) ;
441492 }
442493
494+ #[ test]
495+ fn test_from_static ( ) {
496+ assert_eq ! ( Method :: from_static( b"PROPFIND" ) , Method :: from_bytes( b"PROPFIND" ) . unwrap( ) ) ;
497+ assert_eq ! ( Method :: from_static( b"GET" ) , Method :: from_bytes( b"GET" ) . unwrap( ) ) ;
498+ assert_eq ! ( Method :: from_static( b"GET" ) , Method :: GET ) ;
499+ assert_eq ! ( Method :: from_static( b"123456789012345" ) . to_string( ) , "123456789012345" . to_string( ) ) ;
500+ }
501+
502+ #[ test]
503+ #[ should_panic]
504+ fn test_from_static_too_long ( ) {
505+ Method :: from_static ( b"1234567890123456" ) ;
506+ }
507+
508+ #[ test]
509+ #[ should_panic]
510+ fn test_from_static_bad ( ) {
511+ Method :: from_static ( b"\0 " ) ;
512+ }
513+
443514 #[ test]
444515 fn test_invalid_method ( ) {
445516 assert ! ( Method :: from_str( "" ) . is_err( ) ) ;
0 commit comments