use std::time::Duration;
use crate::{Client, RequestBuilder, Result};
#[inline]
pub fn get(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url)
}
#[inline]
pub fn post(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url).method(crate::Method::POST)
}
#[inline]
pub fn put(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url).method(crate::Method::PUT)
}
#[inline]
pub fn delete(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url).method(crate::Method::DELETE)
}
#[inline]
pub fn patch(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url).method(crate::Method::PATCH)
}
#[inline]
pub fn head(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url).method(crate::Method::HEAD)
}
#[inline]
pub fn options(url: impl Into<String>) -> SimpleRequestBuilder {
SimpleRequestBuilder::new(url).method(crate::Method::OPTIONS)
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub async fn get_json<T: serde::de::DeserializeOwned>(url: impl Into<String>) -> Result<T> {
get(url).send().await?.json().await
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub async fn post_json<T, B>(url: impl Into<String> + crate::IntoUri, body: &B) -> Result<T>
where
T: serde::de::DeserializeOwned,
B: serde::Serialize,
{
let client = crate::Client::new();
let resp = client.post(url).json(body).send().await?;
resp.json().await
}
pub struct SimpleRequestBuilder {
url: String,
method: crate::Method,
bearer_token: Option<String>,
api_key: Option<(String, String)>,
retry_count: Option<u32>,
timeout: Option<Duration>,
headers: Vec<(String, String)>,
}
impl SimpleRequestBuilder {
fn new(url: impl Into<String>) -> Self {
Self {
url: url.into(),
method: crate::Method::GET,
bearer_token: None,
api_key: None,
retry_count: None,
timeout: None,
headers: Vec::new(),
}
}
#[inline]
fn method(mut self, method: crate::Method) -> Self {
self.method = method;
self
}
#[inline]
pub fn bearer_token(mut self, token: impl Into<String>) -> Self {
self.bearer_token = Some(token.into());
self
}
#[inline]
pub fn api_key(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
self.api_key = Some((name.into(), value.into()));
self
}
#[inline]
pub fn retry(mut self, count: u32) -> Self {
self.retry_count = Some(count);
self
}
#[inline]
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
#[inline]
pub fn header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
self.headers.push((name.into(), value.into()));
self
}
pub async fn send(self) -> Result<crate::Response> {
let client = Client::new();
let mut builder = client.request(self.method, &self.url);
if let Some(token) = &self.bearer_token {
let value = format!("Bearer {token}");
builder = builder.header(http::header::AUTHORIZATION, value);
}
if let Some((name, value)) = &self.api_key {
builder = builder.header(name.as_str(), value.as_str());
}
for (name, value) in &self.headers {
builder = builder.header(name.as_str(), value.as_str());
}
if let Some(timeout) = self.timeout {
builder = builder.timeout(timeout);
}
let _ = self.retry_count;
builder.send().await
}
pub fn build(self) -> Result<RequestBuilder> {
let client = Client::new();
let mut builder = client.request(self.method, &self.url);
if let Some(token) = &self.bearer_token {
let value = format!("Bearer {token}");
builder = builder.header(http::header::AUTHORIZATION, value);
}
if let Some((name, value)) = &self.api_key {
builder = builder.header(name.as_str(), value.as_str());
}
for (name, value) in &self.headers {
builder = builder.header(name.as_str(), value.as_str());
}
if let Some(timeout) = self.timeout {
builder = builder.timeout(timeout);
}
Ok(builder)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple_get_builder() {
let builder = get("https://example.com");
assert_eq!(builder.url, "https://example.com");
assert_eq!(builder.method, crate::Method::GET);
}
#[test]
fn test_simple_post_builder() {
let builder = post("https://example.com");
assert_eq!(builder.method, crate::Method::POST);
}
#[test]
fn test_simple_builder_bearer_token() {
let builder = get("https://example.com").bearer_token("my-token");
assert_eq!(builder.bearer_token.as_deref(), Some("my-token"));
}
#[test]
fn test_simple_builder_api_key() {
let builder = get("https://example.com").api_key("X-API-KEY", "key123");
assert!(builder.api_key.is_some());
}
#[test]
fn test_simple_builder_timeout() {
let builder = get("https://example.com").timeout(Duration::from_secs(5));
assert_eq!(builder.timeout, Some(Duration::from_secs(5)));
}
#[test]
fn test_simple_builder_retry() {
let builder = get("https://example.com").retry(3);
assert_eq!(builder.retry_count, Some(3));
}
#[test]
fn test_simple_builder_header() {
let builder = get("https://example.com")
.header("X-Custom", "value")
.header("X-Other", "other");
assert_eq!(builder.headers.len(), 2);
}
}