1use std::sync::Arc;
2
3use super::request::FileListQuery;
4use crate::{
5 ZaiResult,
6 client::{
7 endpoints::{ApiBase, EndpointConfig, build_query, paths},
8 http::{HttpClient, HttpClientConfig, parse_typed_response},
9 },
10};
11
12pub struct FileListRequest {
17 pub key: String,
18 url: String,
19 endpoint_config: EndpointConfig,
20 api_base: ApiBase,
21 query: FileListQuery,
22 _body: (),
23 http_config: Arc<HttpClientConfig>,
24}
25
26impl FileListRequest {
27 pub fn new(key: String) -> Self {
28 let endpoint_config = EndpointConfig::default();
29 let api_base = ApiBase::PaasV4;
30 let url = endpoint_config.url(&api_base, paths::FILES);
31 Self {
32 key,
33 url,
34 endpoint_config,
35 api_base,
36 query: FileListQuery::new(),
37 _body: (),
38 http_config: Arc::new(HttpClientConfig::default()),
39 }
40 }
41
42 fn rebuild_url(&mut self) {
43 let endpoint = self.endpoint_config.url(&self.api_base, paths::FILES);
44 let mut params: Vec<(&str, String)> = Vec::new();
45 if let Some(after) = self.query.after.as_ref() {
46 params.push(("after", after.clone()));
47 }
48 if let Some(purpose) = self.query.purpose.as_ref() {
49 params.push(("purpose", purpose.as_str().to_string()));
50 }
51 if let Some(order) = self.query.order.as_ref() {
52 params.push(("order", order.as_str().to_string()));
53 }
54 if let Some(limit) = self.query.limit.as_ref() {
55 params.push(("limit", limit.to_string()));
56 }
57 self.url = build_query(&endpoint, params);
58 }
59
60 pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
61 self.api_base = ApiBase::Custom(base_url.into());
62 self.rebuild_url();
63 self
64 }
65
66 pub fn with_endpoint_config(mut self, endpoint_config: EndpointConfig) -> Self {
67 self.endpoint_config = endpoint_config;
68 self.rebuild_url();
69 self
70 }
71
72 pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
73 self.http_config = Arc::new(config);
74 self
75 }
76
77 pub fn with_query(mut self, q: FileListQuery) -> Self {
78 self.query = q;
79 self.rebuild_url();
80 self
81 }
82 pub async fn send(&self) -> ZaiResult<super::response::FileListResponse> {
84 let resp = self.get().await?;
85 parse_typed_response::<super::response::FileListResponse>(resp).await
86 }
87
88 pub async fn send_with_query(
90 mut self,
91 q: &super::request::FileListQuery,
92 ) -> ZaiResult<super::response::FileListResponse> {
93 use validator::Validate;
94 q.validate()?;
95 self.query = q.clone();
96 self.rebuild_url();
97 self.send().await
98 }
99}
100
101impl HttpClient for FileListRequest {
102 type Body = ();
103 type ApiUrl = String;
104 type ApiKey = String;
105
106 fn api_url(&self) -> &Self::ApiUrl {
107 &self.url
108 }
109 fn api_key(&self) -> &Self::ApiKey {
110 &self.key
111 }
112 fn body(&self) -> &Self::Body {
113 &self._body
114 }
115
116 fn http_config(&self) -> Arc<HttpClientConfig> {
117 self.http_config.clone()
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124 use crate::client::http::HttpClient;
125
126 #[test]
127 fn query_survives_base_rebuild() {
128 let request = FileListRequest::new("test.12345678901234567890".to_string())
129 .with_query(
130 FileListQuery::new()
131 .with_purpose(crate::file::request::FilePurpose::Batch)
132 .with_limit(2),
133 )
134 .with_base_url("http://127.0.0.1:12345/api/paas/v4");
135
136 assert_eq!(
137 request.api_url(),
138 "http://127.0.0.1:12345/api/paas/v4/files?purpose=batch&limit=2"
139 );
140 }
141
142 #[test]
143 fn query_survives_endpoint_config_rebuild() {
144 let endpoint_config =
145 EndpointConfig::default().with_paas_v4_base("http://127.0.0.1:12345/api/paas/v4");
146 let request = FileListRequest::new("test.12345678901234567890".to_string())
147 .with_query(FileListQuery::new().with_after("cursor").with_limit(10))
148 .with_endpoint_config(endpoint_config);
149
150 assert_eq!(
151 request.api_url(),
152 "http://127.0.0.1:12345/api/paas/v4/files?after=cursor&limit=10"
153 );
154 }
155}