Skip to content

Commit

Permalink
Add Method::from_static
Browse files Browse the repository at this point in the history
Allows creating constant `Method` instances, e.g.:

    const PROPFIND: Method = Method::from_static(b"PROPFIND");

Fixes: #587
  • Loading branch information
WhyNotHugo committed Jun 29, 2023
1 parent 20633e5 commit 7232c97
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,29 @@ impl Method {
}
}

/// Convert static bytes into a `Method`.
///
/// # Panics
///
/// If the input bytes are not a valid method name or if the method name is over 15 bytes.
pub const fn from_static(src: &'static [u8]) -> Method {
match src {
b"OPTIONS" => Method::OPTIONS,
b"GET" => Method::GET,
b"POST" => Method::POST,
b"PUT" => Method::PUT,
b"DELETE" => Method::DELETE,
b"HEAD" => Method::HEAD,
b"TRACE" => Method::TRACE,
b"CONNECT" => Method::CONNECT,
b"PATCH" => Method::PATCH,
_ => {
let inline = InlineExtension::from_static(src);
Method(ExtensionInline(inline))
}
}
}

fn extension_inline(src: &[u8]) -> Result<Method, InvalidMethod> {
let inline = InlineExtension::new(src)?;

Expand Down Expand Up @@ -335,6 +358,34 @@ mod extension {
Ok(InlineExtension(data, src.len() as u8))
}

/// Convert static bytes into an `InlineExtension`.
///
/// # Panics
///
/// If the input bytes are not a valid method name or if the method name is over 15 bytes.
pub const fn from_static(src: &'static [u8]) -> InlineExtension {
let mut i = 0;
let mut dst = [0u8;15];
if src.len() > 15 {
// panicking in const requires Rust 1.57.0
#[allow(unconditional_panic)]
([] as [u8; 0])[0];
}
while i < src.len() {
let byte = src[i] ;
let v = METHOD_CHARS[byte as usize];
if v == 0 {
// panicking in const requires Rust 1.57.0
#[allow(unconditional_panic)]
([] as [u8; 0])[0];
}
dst[i] = byte;
i += 1;
}

InlineExtension(dst, i as u8)
}

pub fn as_str(&self) -> &str {
let InlineExtension(ref data, len) = self;
// Safety: the invariant of InlineExtension ensures that the first
Expand Down Expand Up @@ -440,6 +491,26 @@ mod test {
assert_eq!(Method::GET, &Method::GET);
}

#[test]
fn test_from_static() {
assert_eq!(Method::from_static(b"PROPFIND"), Method::from_bytes(b"PROPFIND").unwrap());
assert_eq!(Method::from_static(b"GET"), Method::from_bytes(b"GET").unwrap());
assert_eq!(Method::from_static(b"GET"), Method::GET);
assert_eq!(Method::from_static(b"123456789012345").to_string(), "123456789012345".to_string());
}

#[test]
#[should_panic]
fn test_from_static_too_long() {
Method::from_static(b"1234567890123456");
}

#[test]
#[should_panic]
fn test_from_static_bad() {
Method::from_static(b"\0");
}

#[test]
fn test_invalid_method() {
assert!(Method::from_str("").is_err());
Expand Down

0 comments on commit 7232c97

Please sign in to comment.