Skip to content

Commit 755c3b4

Browse files
committed
Add Method::from_static
Allows creating constant `Method` instances, e.g.: const PROPFIND: Method = Method::from_static(b"PROPFIND"); Fixes: hyperium#587
1 parent 20633e5 commit 755c3b4

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/method.rs

+71
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)