linger-openai-sdk 0.1.1

Rust-native async SDK for OpenAI APIs with typed requests, streaming, uploads, retries, and pluggable transports.
Documentation
use crate::error::LingerError;
use crate::retry::{NoopRetrySleeper, RetryPolicy, RetrySleeper};
use std::fmt;
use std::sync::Arc;

/// EN: SDK client configuration.
/// 中文:SDK 客户端配置。
#[derive(Clone)]
#[non_exhaustive]
pub struct ClientConfig {
    api_key: String,
    base_url: String,
    organization: Option<String>,
    project: Option<String>,
    retry_policy: RetryPolicy,
    retry_sleeper: Arc<dyn RetrySleeper>,
}

impl ClientConfig {
    /// EN: Starts building a client configuration.
    /// 中文:开始构建客户端配置。
    pub fn builder() -> ClientConfigBuilder {
        ClientConfigBuilder::default()
    }

    /// EN: Returns the configured API key.
    /// 中文:返回已配置的 API key。
    pub(crate) fn api_key(&self) -> &str {
        &self.api_key
    }

    /// EN: Returns the base API URL.
    /// 中文:返回 API 基础 URL。
    pub fn base_url(&self) -> &str {
        &self.base_url
    }

    /// EN: Returns the configured organization header value.
    /// 中文:返回已配置的组织请求头值。
    pub fn organization(&self) -> Option<&str> {
        self.organization.as_deref()
    }

    /// EN: Returns the configured project header value.
    /// 中文:返回已配置的项目请求头值。
    pub fn project(&self) -> Option<&str> {
        self.project.as_deref()
    }

    /// EN: Returns the configured retry policy.
    /// 中文:返回已配置的重试策略。
    pub fn retry_policy(&self) -> &RetryPolicy {
        &self.retry_policy
    }

    /// EN: Returns the configured retry sleeper.
    /// 中文:返回已配置的重试休眠器。
    pub fn retry_sleeper(&self) -> Arc<dyn RetrySleeper> {
        self.retry_sleeper.clone()
    }
}

impl fmt::Debug for ClientConfig {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ClientConfig")
            .field("api_key", &"<redacted>")
            .field("base_url", &self.base_url)
            .field(
                "organization",
                &self.organization.as_ref().map(|_| "<redacted>"),
            )
            .field("project", &self.project.as_ref().map(|_| "<redacted>"))
            .field("retry_policy", &self.retry_policy)
            .field("retry_sleeper", &self.retry_sleeper)
            .finish()
    }
}

/// EN: Builder for SDK client configuration.
/// 中文:SDK 客户端配置构建器。
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct ClientConfigBuilder {
    api_key: Option<String>,
    base_url: String,
    organization: Option<String>,
    project: Option<String>,
    retry_policy: RetryPolicy,
    retry_sleeper: Arc<dyn RetrySleeper>,
}

impl Default for ClientConfigBuilder {
    fn default() -> Self {
        Self {
            api_key: None,
            base_url: "https://api.openai.com".to_string(),
            organization: None,
            project: None,
            retry_policy: RetryPolicy::default(),
            retry_sleeper: Arc::new(NoopRetrySleeper),
        }
    }
}

impl ClientConfigBuilder {
    /// EN: Sets the OpenAI API key used for bearer authentication.
    /// 中文:设置用于 Bearer 认证的 OpenAI API key。
    pub fn api_key(mut self, api_key: impl Into<String>) -> Self {
        self.api_key = Some(api_key.into());
        self
    }

    /// EN: Sets the OpenAI API base URL.
    /// 中文:设置 OpenAI API 基础 URL。
    pub fn base_url(mut self, base_url: impl Into<String>) -> Self {
        self.base_url = base_url.into();
        self
    }

    /// EN: Sets the optional OpenAI organization header.
    /// 中文:设置可选的 OpenAI 组织请求头。
    pub fn organization(mut self, organization: impl Into<String>) -> Self {
        self.organization = Some(organization.into());
        self
    }

    /// EN: Sets the optional OpenAI project header.
    /// 中文:设置可选的 OpenAI 项目请求头。
    pub fn project(mut self, project: impl Into<String>) -> Self {
        self.project = Some(project.into());
        self
    }

    /// EN: Sets the retry policy.
    /// 中文:设置重试策略。
    pub fn retry_policy(mut self, retry_policy: RetryPolicy) -> Self {
        self.retry_policy = retry_policy;
        self
    }

    /// EN: Sets the retry sleeper used between retry attempts.
    /// 中文:设置两次重试之间使用的休眠器。
    pub fn retry_sleeper(mut self, retry_sleeper: Arc<dyn RetrySleeper>) -> Self {
        self.retry_sleeper = retry_sleeper;
        self
    }

    /// EN: Builds and validates the client configuration.
    /// 中文:构建并校验客户端配置。
    pub fn build(self) -> Result<ClientConfig, LingerError> {
        let api_key = self
            .api_key
            .filter(|value| !value.trim().is_empty())
            .ok_or_else(|| LingerError::invalid_config("api_key is required"))?;
        if self.base_url.trim().is_empty() {
            return Err(LingerError::invalid_config("base_url is required"));
        }
        Ok(ClientConfig {
            api_key,
            base_url: self.base_url.trim_end_matches('/').to_string(),
            organization: self.organization,
            project: self.project,
            retry_policy: self.retry_policy,
            retry_sleeper: self.retry_sleeper,
        })
    }
}