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