Jonathan Reem
@jreem
github.com/reem
GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1
Host: net.tutsplus.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120
Pragma: no-cache
Cache-Control: no-cache
pub type Method = String;
pub static Get: Method = "GET";
pub static Post: Method = "POST";
// etc.
request.method = Get;
pub type Method = u16;
pub static Get: Method = 1u16;
pub static Post: Method = 2u16;
// etc.
request.method = Get;
pub struct Method {
name: String,
idempotent: bool,
safe: bool
}
pub static Get: Method = Method {
name: "GET",
idempotent: true,
safe: true
};
pub static Post: Method = Method {
name: "POST",
idempotent: false,
safe: false
};
// etc.
request.method = Get;
pub enum Method {
Get,
Post, // etc.
}
request.method = Get;
pub struct Headers {
data: HashMap<String, String>
}
pub static TransferEncoding: String = "transfer-encoding";
pub static ContentLength: String = "content-length";
// etc.
request.headers.set(TransferEncoding, "Gzip");
pub struct Headers {
data: HashMap<String, HeaderItem>
}
pub enum HeaderItem {
Raw(String),
Typed(Box<Header>)
}
pub trait Header {
fn name() -> String;
fn parse(String) -> Self;
fn display(self) -> String;
}
pub enum TransferEncoding { Gzip, Compress, Deflate, Chunked }
impl Header for TransferEncoding {
fn name() -> String { "transfer-encoding" }
fn parse(raw: String) -> TransferEncoding {
match raw {
"gzip" => Gzip, // etc.
}
}
fn display(self) -> String { self.to_string() }
}
request.headers.set(Gzip);
pub enum Status {
Continue = 100,
SwitchingProtocols = 101,
Processing = 102,
Code103 = 103,
// etc.
}
response.status = Continue;
pub struct Response {
body: TcpStream,
headers: Headers,
headers_written: bool
}
impl Writer for Response {
fn write(&self, msg: Bytes) {
if !self.headers_written {
self.write_headers();
self.headers_written = true;
}
self.body.write(msg);
}
}
response.headers.set(Gzip);
response.write(b"Hello World!");
// Woops
response.headers.set(Compress);
pub struct Fresh; pub struct Streaming;
pub struct Response<WriteStatus> { body: TcpStream, headers: Headers }
impl<W> Response<W> {
fn headers(&self) -> &Headers { &self.headers }
}
impl Response<Fresh> {
fn headers_mut(&mut self) -> &mut Headers { &mut self.headers }
fn start(self) -> Response<Streaming> {
self.write_headers();
Response { body: self.body, headers: self.headers }
}
}
impl Writer for Response<Streaming> {
fn write(&self, msg: Bytes) {
self.body.write(msg);
}
}
response.headers_mut().set(Gzip);
let response = response.start();
response.write(b"Hello World!");
// Compile time error.
response.headers_mut().set(Compress);