1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
use crate::{
	HttpError,
	header::{ RequestHeader, ResponseHeader, header::Header },
	data::{
		Data,
		encodings::{ Ascii, HeaderFieldKey, Uri, Integer }
	}
};
use std::collections::HashMap;


/// A HTTP-response header builder
pub struct RequestBuilder<'a> {
	method: Option<Data<'a, Ascii>>,
	uri: Option<Data<'a, Uri>>,
	version: Option<Data<'a, Ascii>>,
	header_fields: HashMap<Data<'a, HeaderFieldKey>, Data<'a, Ascii>>
}
impl<'a> RequestBuilder<'a> {
	/// Creates a new request builder
	pub fn new() -> Self {
		Self{ method: None, uri: None, version: None, header_fields: HashMap::new() }
	}
	
	/// Sets the request method
	pub fn method(mut self, method: Data<'a, Ascii>) -> Self {
		self.method = Some(method);
		self
	}
	/// Sets the request URI
	pub fn uri(mut self, uri: Data<'a, Uri>) -> Self {
		self.uri = Some(uri);
		self
	}
	/// Sets the HTTP version
	pub fn version(mut self, version: Data<'a, Ascii>) -> Self {
		self.version = Some(version);
		self
	}
	
	/// Inserts a header field with `key`-`value`
	pub fn field(mut self, key: Data<'a, HeaderFieldKey>, value: Data<'a, Ascii>) -> Self {
		self.header_fields.insert(key, value);
		self
	}
	
	/// Builds the request header
	pub fn build(self) -> Result<RequestHeader<'a>, HttpError> {
		// Unwrap status fields
		let method = self.method.ok_or(HttpError::ApiMisuse)?;
		let uri = self.uri.ok_or(HttpError::ApiMisuse)?;
		let version = self.version.ok_or(HttpError::ApiMisuse)?;
		
		Ok(RequestHeader(Header {
			header_line: (method.as_slice(), uri.as_slice(), version.as_slice()),
			header_fields: self.header_fields
		}))
	}
}


/// A HTTP-response header builder
pub struct ResponseBuilder<'a> {
	version: Option<Data<'a, Ascii>>,
	status: Option<Data<'a, Integer>>,
	reason: Option<Data<'a, Ascii>>,
	header_fields: HashMap<Data<'a, HeaderFieldKey>, Data<'a, Ascii>>
}
impl<'a> ResponseBuilder<'a> {
	/// Creates a new response builder
	pub fn new() -> Self {
		Self{ version: None, status: None, reason: None, header_fields: HashMap::new() }
	}
	
	/// Sets the HTTP version to the literal `version`
	pub fn version(mut self, version: Data<'a, Ascii>) -> Self {
		self.version = Some(version);
		self
	}
	/// Sets the status code
	pub fn status(mut self, status: Data<'a, Integer>) -> Self {
		self.status = Some(status);
		self
	}
	/// Sets the status reason
	pub fn reason(mut self, info: Data<'a, Ascii>) -> Self {
		self.reason = Some(info);
		self
	}
	
	/// Inserts a header field with `key`-`value`
	pub fn field(mut self, key: Data<'a, HeaderFieldKey>, value: Data<'a, Ascii>) -> Self {
		self.header_fields.insert(key, value);
		self
	}
	
	/// Builds the response header
	pub fn build(self) -> Result<ResponseHeader<'a>, HttpError> {
		// Unwrap status fields
		let version = self.version.ok_or(HttpError::ApiMisuse)?;
		let status = self.status.ok_or(HttpError::ApiMisuse)?;
		let reason = self.reason.ok_or(HttpError::ApiMisuse)?;
		
		Ok(ResponseHeader(Header {
			header_line: (version.as_slice(), status.as_slice(), reason.as_slice()),
			header_fields: self.header_fields
		}))
	}
}