1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4use validator::Validate;
5
6use super::types::BatchItem;
7use crate::{
8 ZaiResult,
9 client::{
10 endpoints::{ApiBase, EndpointConfig, build_query, paths},
11 http::{HttpClient, HttpClientConfig, parse_typed_response},
12 },
13};
14
15#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
17pub struct BatchesListQuery {
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub after: Option<String>,
21
22 #[serde(skip_serializing_if = "Option::is_none")]
24 #[validate(range(min = 1, max = 100))]
25 pub limit: Option<u32>,
26}
27
28impl Default for BatchesListQuery {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl BatchesListQuery {
35 pub fn new() -> Self {
37 Self {
38 after: None,
39 limit: None,
40 }
41 }
42
43 pub fn with_after(mut self, after: impl Into<String>) -> Self {
45 self.after = Some(after.into());
46 self
47 }
48
49 pub fn with_limit(mut self, limit: u32) -> Self {
51 self.limit = Some(limit);
52 self
53 }
54}
55
56pub struct BatchesListRequest {
58 pub key: String,
60 url: String,
62 endpoint_config: EndpointConfig,
63 api_base: ApiBase,
64 http_config: Arc<HttpClientConfig>,
65 query: BatchesListQuery,
66 _body: (),
68}
69
70impl BatchesListRequest {
71 pub fn new(key: String) -> Self {
73 let endpoint_config = EndpointConfig::default();
74 let api_base = ApiBase::PaasV4;
75 let url = endpoint_config.url(&api_base, paths::BATCHES);
76 Self {
77 key,
78 url,
79 endpoint_config,
80 api_base,
81 http_config: Arc::new(HttpClientConfig::default()),
82 query: BatchesListQuery::new(),
83 _body: (),
84 }
85 }
86
87 fn rebuild_url(&mut self) {
89 let endpoint = self.endpoint_config.url(&self.api_base, paths::BATCHES);
90 let mut params: Vec<(&str, String)> = Vec::new();
91 if let Some(after) = self.query.after.as_ref() {
92 params.push(("after", after.clone()));
93 }
94 if let Some(limit) = self.query.limit.as_ref() {
95 params.push(("limit", limit.to_string()));
96 }
97 self.url = build_query(&endpoint, params);
98 }
99
100 pub fn with_base_url(mut self, base: impl Into<String>) -> Self {
101 self.api_base = ApiBase::Custom(base.into());
102 self.rebuild_url();
103 self
104 }
105
106 pub fn with_endpoint_config(mut self, endpoint_config: EndpointConfig) -> Self {
107 self.endpoint_config = endpoint_config;
108 self.rebuild_url();
109 self
110 }
111
112 pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
113 self.http_config = Arc::new(config);
114 self
115 }
116
117 pub fn with_query(mut self, q: BatchesListQuery) -> Self {
119 self.query = q;
120 self.rebuild_url();
121 self
122 }
123
124 pub async fn send(&self) -> ZaiResult<BatchesListResponse> {
126 let resp: reqwest::Response = self.get().await?;
127
128 let parsed = parse_typed_response::<BatchesListResponse>(resp).await?;
129
130 Ok(parsed)
131 }
132}
133
134impl HttpClient for BatchesListRequest {
135 type Body = ();
136 type ApiUrl = String;
137 type ApiKey = String;
138
139 fn api_url(&self) -> &Self::ApiUrl {
140 &self.url
141 }
142 fn api_key(&self) -> &Self::ApiKey {
143 &self.key
144 }
145 fn body(&self) -> &Self::Body {
146 &self._body
147 }
148
149 fn http_config(&self) -> Arc<HttpClientConfig> {
150 Arc::clone(&self.http_config)
151 }
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
156pub struct BatchesListResponse {
157 #[serde(skip_serializing_if = "Option::is_none")]
159 pub object: Option<ListObject>,
160
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub data: Option<Vec<BatchItem>>,
164
165 #[serde(skip_serializing_if = "Option::is_none")]
167 pub first_id: Option<String>,
168
169 #[serde(skip_serializing_if = "Option::is_none")]
171 pub last_id: Option<String>,
172
173 #[serde(skip_serializing_if = "Option::is_none")]
175 pub has_more: Option<bool>,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
180#[serde(rename_all = "lowercase")]
181pub enum ListObject {
182 List,
184}