103 lines
2.2 KiB
Rust
103 lines
2.2 KiB
Rust
use crate::parse::{Line, Parse, ParseError};
|
|
use core::str::from_utf8;
|
|
|
|
pub const LINE_ENDING: &[u8] = b"\r\n";
|
|
|
|
macro_rules! versions {
|
|
($(($name:ident, $str:expr)),* $(,)?) => {
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
pub enum Version<'a> {
|
|
$($name,)*
|
|
Unknown(&'a [u8]),
|
|
}
|
|
|
|
impl<'a> Parse<'a> for Version<'a> {
|
|
fn parse(data: &'a [u8]) -> Result<(usize, Self), Option<ParseError>> {
|
|
$({
|
|
const STR: &[u8] = $str.as_bytes();
|
|
let len = ((STR.len() <= data.len()) as usize) * STR.len();
|
|
|
|
let data = &data[..len];
|
|
if data.eq_ignore_ascii_case(STR) {
|
|
return Ok((STR.len(), Self::$name));
|
|
}
|
|
};)*
|
|
|
|
Ok((0, Self::Unknown(data)))
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
versions! {
|
|
(V1_0, "http/1.0"),
|
|
(V1_1, "http/1.1"),
|
|
}
|
|
|
|
macro_rules! methods {
|
|
($(($name:ident, $str:expr)),* $(,)?) => {
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
pub enum Method<'a> {
|
|
$($name,)*
|
|
Other(&'a str),
|
|
}
|
|
|
|
|
|
impl<'a> Parse<'a> for Method<'a> {
|
|
fn parse(data: &'a [u8]) -> Result<(usize, Self), Option<ParseError>> {
|
|
$({
|
|
const STR: &[u8] = $str.as_bytes();
|
|
let len = ((STR.len() <= data.len()) as usize) * STR.len();
|
|
|
|
let data = &data[..len];
|
|
if data.eq_ignore_ascii_case(STR) {
|
|
return Ok((STR.len(), Self::$name));
|
|
}
|
|
};)*
|
|
|
|
from_utf8(data).map(|s| (s.len(), Self::Other(s))).map_err(|_| Some(ParseError {
|
|
ctx: "method",
|
|
details: "unknown method was not a valid str",
|
|
}))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
methods! {
|
|
(Get, "GET"),
|
|
(Head, "HEAD"),
|
|
(Options, "OPTIONS"),
|
|
(Trace, "TRACE"),
|
|
(Put, "PUT"),
|
|
(Delete, "DELETE"),
|
|
(Post, "POST"),
|
|
(Patch, "PATCH"),
|
|
(Connect, "CONNECT"),
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
pub struct Status<'a> {
|
|
pub code: u16,
|
|
pub text: &'a str,
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
pub struct RequestLine<'a> {
|
|
pub method: Method<'a>,
|
|
pub target: &'a str,
|
|
pub version: Version<'a>,
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
pub struct StatusLine<'a> {
|
|
pub version: Version<'a>,
|
|
pub status: Status<'a>,
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
pub struct Header<'a> {
|
|
pub name: &'a str,
|
|
pub value: &'a [u8],
|
|
}
|