Skip to main content

zai_rs/knowledge/
document_upload_url.rs

1use serde::{Deserialize, Serialize};
2use validator::Validate;
3
4use super::types::UploadUrlResponse;
5use crate::ZaiResult;
6use crate::client::ZaiClient;
7
8/// Single URL upload detail
9#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
10pub struct UploadUrlDetail {
11    /// Source URL to fetch
12    #[validate(url)]
13    pub url: String,
14    /// Slice type (integer)
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub knowledge_type: Option<i64>,
17    /// Custom separators
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub custom_separator: Option<Vec<String>>,
20    /// Sentence size
21    #[serde(skip_serializing_if = "Option::is_none")]
22    #[validate(range(min = 1))]
23    pub sentence_size: Option<u32>,
24    /// Callback URL
25    #[serde(skip_serializing_if = "Option::is_none")]
26    #[validate(url)]
27    pub callback_url: Option<String>,
28    /// Callback headers
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub callback_header: Option<std::collections::BTreeMap<String, String>>,
31}
32
33impl UploadUrlDetail {
34    /// Create a new upload detail for the given source URL.
35    pub fn new(url: impl Into<String>) -> Self {
36        Self {
37            url: url.into(),
38            knowledge_type: None,
39            custom_separator: None,
40            sentence_size: None,
41            callback_url: None,
42            callback_header: None,
43        }
44    }
45    /// Set the slice/knowledge type.
46    pub fn with_knowledge_type(mut self, t: i64) -> Self {
47        self.knowledge_type = Some(t);
48        self
49    }
50    /// Set custom separators.
51    pub fn with_custom_separator(mut self, seps: Vec<String>) -> Self {
52        self.custom_separator = Some(seps);
53        self
54    }
55    /// Set the sentence size.
56    pub fn with_sentence_size(mut self, size: u32) -> Self {
57        self.sentence_size = Some(size);
58        self
59    }
60    /// Set the callback URL.
61    pub fn with_callback_url(mut self, url: impl Into<String>) -> Self {
62        self.callback_url = Some(url.into());
63        self
64    }
65    /// Set the callback headers.
66    pub fn with_callback_header(
67        mut self,
68        headers: std::collections::BTreeMap<String, String>,
69    ) -> Self {
70        self.callback_header = Some(headers);
71        self
72    }
73}
74
75/// Upload URL request body
76#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
77pub struct UploadUrlBody {
78    /// Upload detail list (at least 1)
79    #[validate(length(min = 1))]
80    pub upload_detail: Vec<UploadUrlDetail>,
81    /// Knowledge base id
82    #[validate(length(min = 1))]
83    pub knowledge_id: String,
84}
85
86impl UploadUrlBody {
87    /// Create a new upload body for the given knowledge base id.
88    pub fn new(knowledge_id: impl Into<String>) -> Self {
89        Self {
90            upload_detail: Vec::new(),
91            knowledge_id: knowledge_id.into(),
92        }
93    }
94    /// Append a fully-built [`UploadUrlDetail`].
95    pub fn add_detail(mut self, detail: UploadUrlDetail) -> Self {
96        self.upload_detail.push(detail);
97        self
98    }
99    /// Convenience: append a detail built from a single URL.
100    pub fn add_url(mut self, url: impl Into<String>) -> Self {
101        self.upload_detail.push(UploadUrlDetail::new(url));
102        self
103    }
104}
105
106/// Upload URL request (POST /llm-application/open/document/upload_url)
107///
108/// Credentials and transport live on the [`ZaiClient`], passed to
109/// [`send_via`](Self::send_via).
110pub struct DocumentUploadUrlRequest {
111    body: UploadUrlBody,
112}
113
114impl DocumentUploadUrlRequest {
115    /// Create a new upload-by-URL request with the given body.
116    pub fn new(body: UploadUrlBody) -> Self {
117        Self { body }
118    }
119
120    /// Borrow the underlying [`UploadUrlBody`] mutably.
121    pub fn body_mut(&mut self) -> &mut UploadUrlBody {
122        &mut self.body
123    }
124
125    /// Validate and send via a [`ZaiClient`], returning the typed response.
126    pub async fn send_via(&self, client: &ZaiClient) -> ZaiResult<UploadUrlResponse> {
127        self.body.validate()?;
128        let route = crate::client::routes::DOCUMENTS_UPLOAD_URL;
129        let url = client.endpoints().resolve_route(route, &[])?;
130        client
131            .send_json::<_, UploadUrlResponse>(route.method(), url, &self.body)
132            .await
133    }
134}