@@ -134,6 +134,29 @@ impl Method {
134134 }
135135 }
136136
137+ /// Convert static bytes into a `Method`.
138+ ///
139+ /// # Panics
140+ ///
141+ /// If the input bytes are not a valid method name or if the method name is over 15 bytes.
142+ pub const fn from_static ( src : & ' static [ u8 ] ) -> Method {
143+ match src {
144+ b"OPTIONS" => Method :: OPTIONS ,
145+ b"GET" => Method :: GET ,
146+ b"POST" => Method :: POST ,
147+ b"PUT" => Method :: PUT ,
148+ b"DELETE" => Method :: DELETE ,
149+ b"HEAD" => Method :: HEAD ,
150+ b"TRACE" => Method :: TRACE ,
151+ b"CONNECT" => Method :: CONNECT ,
152+ b"PATCH" => Method :: PATCH ,
153+ _ => {
154+ let inline = InlineExtension :: from_static ( src) ;
155+ Method ( ExtensionInline ( inline) )
156+ }
157+ }
158+ }
159+
137160 fn extension_inline ( src : & [ u8 ] ) -> Result < Method , InvalidMethod > {
138161 let inline = InlineExtension :: new ( src) ?;
139162
@@ -330,6 +353,34 @@ mod extension {
330353 Ok ( InlineExtension ( data, src. len ( ) as u8 ) )
331354 }
332355
356+ /// Convert static bytes into an `InlineExtension`.
357+ ///
358+ /// # Panics
359+ ///
360+ /// If the input bytes are not a valid method name or if the method name is over 15 bytes.
361+ pub const fn from_static ( src : & ' static [ u8 ] ) -> InlineExtension {
362+ let mut i = 0 ;
363+ let mut dst = [ 0u8 ; 15 ] ;
364+ if src. len ( ) > 15 {
365+ // panicking in const requires Rust 1.57.0
366+ #[ allow( unconditional_panic) ]
367+ ( [ ] as [ u8 ; 0 ] ) [ 0 ] ;
368+ }
369+ while i < src. len ( ) {
370+ let byte = src[ i] ;
371+ let v = METHOD_CHARS [ byte as usize ] ;
372+ if v == 0 {
373+ // panicking in const requires Rust 1.57.0
374+ #[ allow( unconditional_panic) ]
375+ ( [ ] as [ u8 ; 0 ] ) [ 0 ] ;
376+ }
377+ dst[ i] = byte;
378+ i += 1 ;
379+ }
380+
381+ InlineExtension ( dst, i as u8 )
382+ }
383+
333384 pub fn as_str ( & self ) -> & str {
334385 let InlineExtension ( ref data, len) = self ;
335386 // Safety: the invariant of InlineExtension ensures that the first
@@ -436,6 +487,26 @@ mod test {
436487 assert_eq ! ( Method :: GET , & Method :: GET ) ;
437488 }
438489
490+ #[ test]
491+ fn test_from_static ( ) {
492+ assert_eq ! ( Method :: from_static( b"PROPFIND" ) , Method :: from_bytes( b"PROPFIND" ) . unwrap( ) ) ;
493+ assert_eq ! ( Method :: from_static( b"GET" ) , Method :: from_bytes( b"GET" ) . unwrap( ) ) ;
494+ assert_eq ! ( Method :: from_static( b"GET" ) , Method :: GET ) ;
495+ assert_eq ! ( Method :: from_static( b"123456789012345" ) . to_string( ) , "123456789012345" . to_string( ) ) ;
496+ }
497+
498+ #[ test]
499+ #[ should_panic]
500+ fn test_from_static_too_long ( ) {
501+ Method :: from_static ( b"1234567890123456" ) ;
502+ }
503+
504+ #[ test]
505+ #[ should_panic]
506+ fn test_from_static_bad ( ) {
507+ Method :: from_static ( b"\0 " ) ;
508+ }
509+
439510 #[ test]
440511 fn test_invalid_method ( ) {
441512 assert ! ( Method :: from_str( "" ) . is_err( ) ) ;
0 commit comments