lib_client_openrouter/
auth.rs

1//! Authentication strategies for the OpenRouter API.
2
3use crate::error::Result;
4use async_trait::async_trait;
5use reqwest::header::HeaderMap;
6
7/// Authentication strategy trait.
8#[async_trait]
9pub trait AuthStrategy: Send + Sync {
10    /// Apply authentication to the request headers.
11    async fn apply(&self, headers: &mut HeaderMap) -> Result<()>;
12}
13
14/// API key authentication (Bearer token).
15#[derive(Debug, Clone)]
16pub struct ApiKeyAuth {
17    api_key: String,
18    site_url: Option<String>,
19    site_name: Option<String>,
20}
21
22impl ApiKeyAuth {
23    /// Create a new API key authentication strategy.
24    pub fn new(api_key: impl Into<String>) -> Self {
25        Self {
26            api_key: api_key.into(),
27            site_url: None,
28            site_name: None,
29        }
30    }
31
32    /// Set the site URL (sent as HTTP-Referer header).
33    /// This helps OpenRouter track usage and may unlock higher rate limits.
34    pub fn with_site_url(mut self, url: impl Into<String>) -> Self {
35        self.site_url = Some(url.into());
36        self
37    }
38
39    /// Set the site name (sent as X-Title header).
40    /// This is displayed in OpenRouter's dashboard.
41    pub fn with_site_name(mut self, name: impl Into<String>) -> Self {
42        self.site_name = Some(name.into());
43        self
44    }
45}
46
47#[async_trait]
48impl AuthStrategy for ApiKeyAuth {
49    async fn apply(&self, headers: &mut HeaderMap) -> Result<()> {
50        let auth_value = format!("Bearer {}", self.api_key);
51        headers.insert("Authorization", auth_value.parse().unwrap());
52
53        if let Some(url) = &self.site_url {
54            headers.insert("HTTP-Referer", url.parse().unwrap());
55        }
56
57        if let Some(name) = &self.site_name {
58            headers.insert("X-Title", name.parse().unwrap());
59        }
60
61        Ok(())
62    }
63}