mod private
{
use crate::error::{ OpenAiCompatError, Result };
use crate::environment::OpenAiCompatEnvironment;
use core::time::Duration;
use reqwest::Client as HttpClient;
#[ derive( Debug ) ]
pub struct Client< E >
where
E : OpenAiCompatEnvironment,
{
http_client : HttpClient,
environment : E,
}
impl< E > Client< E >
where
E : OpenAiCompatEnvironment,
{
#[ inline ]
pub fn build( env : E ) -> Result< Self >
{
let http_client = HttpClient::builder()
.timeout( env.timeout() )
.connect_timeout( Duration::from_secs( 15 ) )
.build()
.map_err( | e | OpenAiCompatError::Environment( e.to_string() ) )?;
Ok( Self { http_client, environment : env } )
}
#[ inline ]
pub async fn post< I, O >( &self, path : &str, body : &I ) -> Result< O >
where
I : serde::Serialize,
O : serde::de::DeserializeOwned,
{
let url = format!( "{}{}", self.environment.base_url(), path );
let headers = self.environment.headers()?;
let response = self.http_client
.post( &url )
.headers( headers )
.json( body )
.send()
.await
.map_err( OpenAiCompatError::from )?;
Self::handle_response( response ).await
}
#[ inline ]
pub async fn get< O >( &self, path : &str ) -> Result< O >
where
O : serde::de::DeserializeOwned,
{
let url = format!( "{}{}", self.environment.base_url(), path );
let headers = self.environment.headers()?;
let response = self.http_client
.get( &url )
.headers( headers )
.send()
.await
.map_err( OpenAiCompatError::from )?;
Self::handle_response( response ).await
}
async fn handle_response< O >( response : reqwest::Response ) -> Result< O >
where
O : serde::de::DeserializeOwned,
{
let status = response.status();
if status.is_success()
{
response
.json::< O >()
.await
.map_err( OpenAiCompatError::from )
.map_err( Into::into )
}
else
{
let body = response
.text()
.await
.unwrap_or_else( | _ | status.to_string() );
Err( OpenAiCompatError::Api( body ).into() )
}
}
}
}
crate::mod_interface!
{
exposed use
{
Client,
};
}