Skip to main content

kagi_sdk/
config.rs

1use std::time::Duration;
2
3use url::Url;
4
5use crate::error::KagiError;
6
7#[derive(Clone, Debug)]
8pub struct ClientConfig {
9    pub base_url: Url,
10    pub timeout: Duration,
11    pub user_agent: String,
12}
13
14impl Default for ClientConfig {
15    fn default() -> Self {
16        Self {
17            base_url: Url::parse("https://kagi.com").expect("static URL is valid"),
18            timeout: Duration::from_secs(20),
19            user_agent: format!("kagi-sdk-rust/{}", env!("CARGO_PKG_VERSION")),
20        }
21    }
22}
23
24impl ClientConfig {
25    pub fn with_base_url(mut self, base_url: Url) -> Self {
26        self.base_url = base_url;
27        self
28    }
29
30    pub fn with_timeout(mut self, timeout: Duration) -> Self {
31        self.timeout = timeout;
32        self
33    }
34
35    pub fn with_user_agent(mut self, user_agent: impl Into<String>) -> Self {
36        self.user_agent = user_agent.into();
37        self
38    }
39
40    pub(crate) fn validate(&self) -> Result<(), KagiError> {
41        if !matches!(self.base_url.scheme(), "http" | "https") {
42            return Err(KagiError::InvalidClientConfiguration {
43                reason: "base_url must use http or https".to_string(),
44            });
45        }
46
47        if self.timeout.is_zero() {
48            return Err(KagiError::InvalidClientConfiguration {
49                reason: "timeout must be greater than zero".to_string(),
50            });
51        }
52
53        if self.user_agent.trim().is_empty() {
54            return Err(KagiError::InvalidClientConfiguration {
55                reason: "user_agent cannot be empty".to_string(),
56            });
57        }
58
59        Ok(())
60    }
61}