Skip to content

Commit b275280

Browse files
committed
Add Method::from_static
Allows creating constant `Method` instances, e.g.: const PROPFIND: Method = Method::from_static(b"PROPFIND"); Fixes: #587
1 parent 63102bc commit b275280

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/method.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)