async_dashscope/
config.rs1use derive_builder::Builder;
8use reqwest::header::AUTHORIZATION;
9use secrecy::{ExposeSecret as _, SecretString};
10
11pub const DASHSCOPE_API_BASE: &str = "https://dashscope.aliyuncs.com/api/v1";
12
13#[derive(Debug, Builder, Clone)]
25#[builder(setter(into))]
26pub struct Config {
27 #[builder(setter(into, strip_option))]
28 #[builder(default = "self.default_base_url()")]
29 api_base: Option<String>,
30 api_key: SecretString,
31}
32
33impl ConfigBuilder {
34 fn default_base_url(&self) -> Option<String> {
35 Some(DASHSCOPE_API_BASE.to_string())
36 }
37}
38
39impl Config {
40 pub fn url(&self, path: &str) -> String {
41 let n_url = format!(
42 "{}/{}",
43 self.api_base.clone()
44 .unwrap_or(DASHSCOPE_API_BASE.to_string())
45 .trim_end_matches('/'),
46 path.trim_start_matches('/')
47 );
48 n_url.trim_end_matches('/').to_string()
49 }
50 pub fn headers(&self) -> reqwest::header::HeaderMap {
51 let mut headers = reqwest::header::HeaderMap::new();
52 headers.insert("Content-Type", "application/json".parse().unwrap());
53 headers.insert(
54 AUTHORIZATION,
55 format!("Bearer {}", self.api_key.expose_secret())
56 .parse()
57 .unwrap(),
58 );
59 headers
60 }
61
62 pub fn set_api_key(&mut self, api_key: SecretString) {
63 self.api_key = api_key;
64 }
65}
66
67impl Default for Config {
68 fn default() -> Self {
69 Self {
70 api_base: Some(DASHSCOPE_API_BASE.to_string()),
71 api_key: std::env::var("DASHSCOPE_API_KEY")
72 .unwrap_or_else(|_| "".to_string())
73 .into(),
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_url_normal_case() {
84 let instance = ConfigBuilder::default()
85 .api_base("https://example.com")
86 .api_key("test")
87 .build()
88 .unwrap();
89 assert_eq!(instance.url("/v1"), "https://example.com/v1");
90 }
91
92 #[test]
93 fn test_url_empty_path() {
94 let instance = ConfigBuilder::default()
95 .api_base("http://localhost:8080")
96 .api_key("test")
97 .build()
98 .unwrap();
99 assert_eq!(instance.url(""), "http://localhost:8080");
100 }
101
102 #[test]
103 fn test_url_empty_api_base() {
104 let instance = ConfigBuilder::default().api_key("test").build().unwrap();
105 assert_eq!(
106 instance.url("/test"),
107 format!("{}/test", DASHSCOPE_API_BASE).as_str()
108 );
109 }
110
111 #[test]
112 fn test_url_slash_in_both_parts() {
113 let instance = ConfigBuilder::default()
114 .api_base("https://a.com/")
115 .api_key("test")
116 .build()
117 .unwrap(); assert_eq!(instance.url("/b"), "https://a.com/b");
119 }
120
121 #[test]
122 fn test_url_no_slash_in_path() {
123 let instance = ConfigBuilder::default()
124 .api_base("https://a.com")
125 .api_key("test")
126 .build()
127 .unwrap();
128 assert_eq!(instance.url("b"), "https://a.com/b");
129 }
130
131 #[test]
132 fn test_api_key() {
133 let instance = ConfigBuilder::default()
134 .api_base("https://example.com")
135 .api_key("test")
136 .build()
137 .unwrap();
138 assert_eq!(
139 instance.headers().get("Authorization").unwrap(),
140 "Bearer test"
141 );
142 }
143}