Skip to content

Commit b2fa38f

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 24bbec2 commit b2fa38f

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

src/method.rs

+67
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 characters.
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,30 @@ 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 characters.
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+
panic!("Method name may not be over 15 characters.");
371+
}
372+
while i < src.len() {
373+
let byte = src[i] ;
374+
let v = METHOD_CHARS[byte as usize];
375+
if v == 0 {
376+
panic!("Invalid byte for method name.");
377+
}
378+
dst[i] = byte;
379+
i += 1;
380+
}
381+
382+
InlineExtension(dst, i as u8)
383+
}
384+
338385
pub fn as_str(&self) -> &str {
339386
let InlineExtension(ref data, len) = self;
340387
// Safety: the invariant of InlineExtension ensures that the first
@@ -440,6 +487,26 @@ mod test {
440487
assert_eq!(Method::GET, &Method::GET);
441488
}
442489

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+
443510
#[test]
444511
fn test_invalid_method() {
445512
assert!(Method::from_str("").is_err());

0 commit comments

Comments
 (0)