use std::{error::Error, fs::File};
use reqwest::{Client, Request, Response};
use tracing::{debug, error, info, instrument, span, trace, warn, Instrument, Level};
use crate::{
api::file::File as BaserowFile,
error::{FileUploadError, TokenAuthError},
BaserowTable, Configuration, TableField,
};
#[async_trait::async_trait]
pub trait RequestTracing {
#[instrument(skip(self, client, request), fields(method = %request.method(), url = %request.url()), err)]
async fn trace_request(&self, client: &Client, request: Request) -> reqwest::Result<Response> {
let span = span!(
Level::DEBUG,
"http_request",
method = %request.method(),
url = %request.url(),
);
async move {
debug!("Sending HTTP request");
trace!(headers = ?request.headers(), "Request headers");
let response = client.execute(request).await?;
let status = response.status();
if status.is_success() {
info!(status = %status, "HTTP request successful");
trace!(headers = ?response.headers(), "Response headers");
} else {
error!(status = %status, "HTTP request failed");
warn!(headers = ?response.headers(), "Failed response headers");
}
Ok(response)
}
.instrument(span)
.await
}
}
impl<T: BaserowClient + ?Sized> RequestTracing for T {}
#[async_trait::async_trait]
pub trait BaserowClient: RequestTracing {
async fn token_auth(&self) -> Result<Box<dyn BaserowClient>, TokenAuthError>;
async fn table_fields(&self, table_id: u64) -> Result<Vec<TableField>, Box<dyn Error>>;
fn table_by_id(&self, id: u64) -> BaserowTable;
async fn upload_file(
&self,
file: File,
filename: String,
) -> Result<BaserowFile, FileUploadError>;
async fn upload_file_via_url(&self, url: &str) -> Result<BaserowFile, FileUploadError>;
fn get_configuration(&self) -> Configuration;
fn get_client(&self) -> Client;
}