1use std::sync::Arc;
2
3use crate::client::{
4 endpoints::{ApiBase, EndpointConfig, join_url, paths},
5 http::{HttpClient, HttpClientConfig},
6};
7
8pub struct FileContentRequest {
10 pub key: String,
11 url: String,
12 endpoint_config: EndpointConfig,
13 api_base: ApiBase,
14 file_id: String,
15 http_config: Arc<HttpClientConfig>,
16 _body: (),
17}
18
19impl FileContentRequest {
20 pub fn new(key: String, file_id: impl Into<String>) -> Self {
21 let file_id = file_id.into();
22 let endpoint_config = EndpointConfig::default();
23 let api_base = ApiBase::PaasV4;
24 let url = endpoint_config.url(
25 &api_base,
26 &join_url(&join_url(paths::FILES, &file_id), "content"),
27 );
28 Self {
29 key,
30 url,
31 endpoint_config,
32 api_base,
33 file_id,
34 http_config: Arc::new(HttpClientConfig::default()),
35 _body: (),
36 }
37 }
38
39 fn rebuild_url(&mut self) {
40 self.url = self.endpoint_config.url(
41 &self.api_base,
42 &join_url(&join_url(paths::FILES, &self.file_id), "content"),
43 );
44 }
45
46 pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
47 self.api_base = ApiBase::Custom(base_url.into());
48 self.rebuild_url();
49 self
50 }
51
52 pub fn with_endpoint_config(mut self, endpoint_config: EndpointConfig) -> Self {
53 self.endpoint_config = endpoint_config;
54 self.rebuild_url();
55 self
56 }
57
58 pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
59 self.http_config = Arc::new(config);
60 self
61 }
62
63 pub async fn send(&self) -> crate::ZaiResult<Vec<u8>> {
65 let resp: reqwest::Response = self.get().await?;
66
67 let status = resp.status();
68
69 if !status.is_success() {
70 let text = resp.text().await.unwrap_or_default();
71
72 return Err(crate::client::error::ZaiError::from_api_response(
73 status.as_u16(),
74 0,
75 text,
76 ));
77 }
78
79 let bytes = resp.bytes().await?;
80 Ok(bytes.to_vec())
81 }
82
83 pub async fn send_to<P: AsRef<std::path::Path>>(&self, path: P) -> crate::ZaiResult<usize> {
86 let bytes = self.send().await?;
87
88 let p = path.as_ref();
89
90 if let Some(parent) = p.parent()
91 && !parent.as_os_str().is_empty()
92 {
93 std::fs::create_dir_all(parent)?;
94 }
95 use std::io::Write;
96 let mut f = std::fs::File::create(p)?;
97 f.write_all(&bytes)?;
98 Ok(bytes.len())
99 }
100}
101
102impl HttpClient for FileContentRequest {
103 type Body = ();
104 type ApiUrl = String;
105 type ApiKey = String;
106
107 fn api_url(&self) -> &Self::ApiUrl {
108 &self.url
109 }
110 fn api_key(&self) -> &Self::ApiKey {
111 &self.key
112 }
113 fn body(&self) -> &Self::Body {
114 &self._body
115 }
116
117 fn http_config(&self) -> Arc<HttpClientConfig> {
118 self.http_config.clone()
119 }
120}