use std::io::Write;
use super::request::HttpRequest;
use super::types::HttpMethod;
pub struct RequestBuilder {
request: HttpRequest,
}
impl RequestBuilder {
pub fn get(url: impl Into<String>) -> Option<Self> {
HttpRequest::new(url).map(|mut req| {
req.method = HttpMethod::GET;
Self { request: req }
})
}
pub fn post(url: impl Into<String>) -> Option<Self> {
HttpRequest::new(url).map(|mut req| {
req.method = HttpMethod::POST;
Self { request: req }
})
}
pub fn put(url: impl Into<String>) -> Option<Self> {
HttpRequest::new(url).map(|mut req| {
req.method = HttpMethod::PUT;
Self { request: req }
})
}
pub fn delete(url: impl Into<String>) -> Option<Self> {
HttpRequest::new(url).map(|mut req| {
req.method = HttpMethod::DELETE;
Self { request: req }
})
}
pub fn patch(url: impl Into<String>) -> Option<Self> {
HttpRequest::new(url).map(|mut req| {
req.method = HttpMethod::PATCH;
Self { request: req }
})
}
pub fn header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.request = self.request.header(key, value);
self
}
pub fn param(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.request = self.request.param(key, value);
self
}
pub fn body(mut self, body: impl Into<String>) -> Self {
self.request = self.request.body(body);
self
}
pub fn json(self, body: impl Into<String>) -> Self {
self.header("Content-Type", "application/json").body(body)
}
pub fn form(self, body: impl Into<String>) -> Self {
self.header("Content-Type", "application/x-www-form-urlencoded")
.body(body)
}
pub fn bearer_auth(self, token: impl Into<String>) -> Self {
self.header("Authorization", format!("Bearer {}", token.into()))
}
pub fn basic_auth(self, username: impl Into<String>, password: impl Into<String>) -> Self {
let credentials = format!("{}:{}", username.into(), password.into());
let encoded = base64_encode(credentials.as_bytes());
let mut encoder = Vec::new();
let _ = write!(encoder, "Basic {}", encoded);
self.header(
"Authorization",
String::from_utf8(encoder).unwrap_or_default(),
)
}
pub fn build(self) -> HttpRequest {
self.request
}
}
#[doc(hidden)]
pub fn base64_encode(data: &[u8]) -> String {
const ALPHABET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut result = String::new();
let chunks = data.chunks(3);
for chunk in chunks {
let b0 = chunk[0] as usize;
let b1 = chunk.get(1).copied().unwrap_or(0) as usize;
let b2 = chunk.get(2).copied().unwrap_or(0) as usize;
result.push(ALPHABET[b0 >> 2] as char);
result.push(ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)] as char);
if chunk.len() > 1 {
result.push(ALPHABET[((b1 & 0x0F) << 2) | (b2 >> 6)] as char);
} else {
result.push('=');
}
if chunk.len() > 2 {
result.push(ALPHABET[b2 & 0x3F] as char);
} else {
result.push('=');
}
}
result
}