mod private
{
use crate::error::{ OpenAiCompatError, Result };
use core::time::Duration;
use reqwest::header;
pub trait OpenAiCompatEnvironment : Send + Sync + 'static
{
fn api_key( &self ) -> &str;
fn base_url( &self ) -> &str;
fn timeout( &self ) -> Duration;
#[ inline ]
fn headers( &self ) -> Result< header::HeaderMap >
{
let mut map = header::HeaderMap::new();
let auth_value = format!( "Bearer {}", self.api_key() )
.parse::< header::HeaderValue >()
.map_err( | e | OpenAiCompatError::InvalidApiKey( e.to_string() ) )?;
map.insert( header::AUTHORIZATION, auth_value );
map.insert
(
header::CONTENT_TYPE,
header::HeaderValue::from_static( "application/json" ),
);
Ok( map )
}
}
#[ allow( dead_code ) ]
#[ derive( Debug, Clone ) ]
pub struct OpenAiCompatEnvironmentImpl
{
api_key : String,
base_url : String,
timeout : Duration,
}
impl OpenAiCompatEnvironmentImpl
{
pub const DEFAULT_BASE_URL : &'static str = "https://api.openai.com/v1/";
pub const DEFAULT_TIMEOUT_SECS : u64 = 30;
#[ inline ]
pub fn new( api_key : impl Into< String > ) -> Result< Self >
{
let api_key = api_key.into();
if api_key.trim().is_empty()
{
return Err
(
OpenAiCompatError::InvalidApiKey( "API key must not be empty or whitespace-only".to_owned() ).into()
);
}
Ok( Self
{
api_key,
base_url : Self::DEFAULT_BASE_URL.to_owned(),
timeout : Duration::from_secs( Self::DEFAULT_TIMEOUT_SECS ),
})
}
#[ must_use ]
#[ inline ]
pub fn with_base_url( mut self, base_url : impl Into< String > ) -> Self
{
self.base_url = base_url.into();
self
}
#[ must_use ]
#[ inline ]
pub fn with_timeout( mut self, timeout : Duration ) -> Self
{
self.timeout = timeout;
self
}
}
impl OpenAiCompatEnvironment for OpenAiCompatEnvironmentImpl
{
#[ inline ]
fn api_key( &self ) -> &str
{
&self.api_key
}
#[ inline ]
fn base_url( &self ) -> &str
{
&self.base_url
}
#[ inline ]
fn timeout( &self ) -> Duration
{
self.timeout
}
}
}
crate::mod_interface!
{
exposed use
{
OpenAiCompatEnvironment,
OpenAiCompatEnvironmentImpl,
};
}