Files
my-website-v2/backend/task/src/utils/request.rs

86 lines
2.6 KiB
Rust
Raw Normal View History

2025-06-29 23:41:20 -04:00
use reqwest::StatusCode;
use std::env;
use std::time::Duration;
#[derive(Debug)]
pub struct Request<'a> {
pub client: reqwest::Client,
pub base_url: Box<str>,
pub full_url: Option<&'a str>,
}
#[derive(Debug)]
pub enum Response<T> {
Json(T),
Xml(String),
Text(String),
Bytes(Vec<u8>),
}
impl<'a> Request<'a> {
pub fn new() -> Self {
Request {
client: reqwest::ClientBuilder::new()
.use_rustls_tls()
.timeout(Duration::from_secs(30))
.build()
.unwrap(),
base_url: env::var("BASE_URI_API")
.expect("Environment variable BASE_URI_API is not found")
.into_boxed_str(),
full_url: None,
}
}
pub async fn request_url<T>(
&self,
url: &String,
) -> Result<Response<T>, Box<dyn std::error::Error>>
where
T: for<'de> serde::Deserialize<'de>,
{
println!("{}", url);
let api_result = match self.client.get(url).send().await {
Ok(r) => r,
Err(e) => return Err(Box::new(e)),
};
match api_result.status() {
StatusCode::OK => {
// TODO: handle errors here
let content_type = api_result
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap();
if content_type.contains("application/json") {
match api_result.json::<T>().await {
Ok(j) => Ok(Response::Json(j)),
Err(e) => return Err(Box::new(e)),
}
} else if content_type.contains("application/xml") {
match api_result.text().await {
Ok(x) => Ok(Response::Xml(x)),
Err(e) => return Err(Box::new(e)),
}
} else if content_type.starts_with("text/") {
match api_result.text().await {
Ok(t) => Ok(Response::Text(t)),
Err(e) => return Err(Box::new(e)),
}
} else {
match api_result.bytes().await {
Ok(b) => Ok(Response::Bytes(b.to_vec())),
Err(e) => Err(Box::new(e)),
}
}
}
status => Err(Box::new(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Unexpected status code: {}", status),
))),
}
}
}