Created
August 28, 2019 15:19
-
-
Save dustinknopoff/f26f575e85425b11aa6da0c48adca7df to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::convert::TryFrom; | |
#[derive(Debug, Copy, Clone)] | |
enum HttpMethod { | |
GET, | |
POST, | |
PUT | |
} | |
impl TryFrom<String> for HttpMethod { | |
type Error = &'static str; | |
fn try_from(value: String) -> Result<Self, Self::Error> { | |
use HttpMethod::*; | |
match value.as_ref() { | |
"GET" => Ok(GET), | |
"POST" => Ok(POST), | |
"PUT" => Ok(PUT), | |
_ => Err("HTTP Method is invalid.") | |
} | |
} | |
} | |
#[derive(Debug, Clone)] | |
struct HttpHeader { | |
method: HttpMethod, | |
path: String | |
} | |
impl HttpHeader { | |
fn new(method: HttpMethod, path: String) -> Self { | |
HttpHeader { | |
method, path | |
} | |
} | |
} | |
#[derive(Debug, Default, Clone)] | |
struct HttpHeaderBuilder { | |
method: Option<HttpMethod>, | |
path: Option<String>, | |
state: Machine | |
} | |
impl TryFrom<HttpHeaderBuilder> for HttpHeader { | |
type Error = &'static str; | |
fn try_from(value: HttpHeaderBuilder) -> Result<Self, Self::Error> { | |
if let Some(method) = value.method { | |
if let Some(path) = value.path { | |
Ok(HttpHeader::new(method, path)) | |
} else { | |
Err("No HTTP Method found.") | |
} | |
} else { | |
Err("No HTTP Method found.") | |
} | |
} | |
} | |
impl HttpHeaderBuilder { | |
fn extract_value(&mut self, saved: String) { | |
match self.state { | |
Machine::METHOD => { | |
match HttpMethod::try_from(saved) { | |
Ok(val) => self.method = Some(val), | |
Err(msg) => panic!(msg) | |
}; | |
self.state = Machine::PATH; | |
}, | |
Machine::PATH => { | |
self.path = Some(saved); | |
self.state = Machine::VERSION; | |
} | |
_ => {} | |
} | |
} | |
} | |
#[derive(Debug, Copy, Clone)] | |
enum Machine { | |
METHOD, | |
PATH, | |
VERSION, | |
FROM, | |
USER_AGENT | |
} | |
impl Default for Machine { | |
fn default() -> Machine { | |
Machine::METHOD | |
} | |
} | |
fn main() { | |
let src = String::from("GET /path/file.html HTTP/1.0 | |
From: [email protected] | |
User-Agent: HTTPTool/1.0"); | |
let ret:(HttpHeaderBuilder, String) = src.chars().fold((Default::default(), String::new()), |acc, curr| { | |
let (mut header, mut saved) = acc; | |
if curr.is_ascii_whitespace() { | |
header.extract_value(saved); | |
saved = String::new(); | |
} else { | |
saved.push(curr); | |
} | |
(header, saved) | |
}); | |
let header = HttpHeader::try_from(ret.0); | |
dbg!(&header); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment