Skip to main content

zai_rs/knowledge/
document_list.rs

1use std::sync::Arc;
2
3use super::types::DocumentListResponse;
4use crate::{
5    ZaiResult,
6    client::{
7        endpoints::{ApiBase, EndpointConfig, build_query, paths},
8        http::{HttpClient, HttpClientConfig, parse_typed_response},
9    },
10};
11
12/// Query parameters for listing documents under a knowledge base
13#[derive(Debug, Clone, serde::Serialize, validator::Validate)]
14pub struct DocumentListQuery {
15    /// Knowledge base id (required)
16    #[validate(length(min = 1))]
17    pub knowledge_id: String,
18    /// Page index (default 1)
19    #[serde(skip_serializing_if = "Option::is_none")]
20    #[validate(range(min = 1))]
21    pub page: Option<u32>,
22    /// Page size (default 10)
23    #[serde(skip_serializing_if = "Option::is_none")]
24    #[validate(range(min = 1))]
25    pub size: Option<u32>,
26    /// Document name filter
27    #[serde(skip_serializing_if = "Option::is_none")]
28    #[validate(length(min = 1))]
29    pub word: Option<String>,
30}
31
32impl DocumentListQuery {
33    pub fn new(knowledge_id: impl Into<String>) -> Self {
34        Self {
35            knowledge_id: knowledge_id.into(),
36            page: Some(1),
37            size: Some(10),
38            word: None,
39        }
40    }
41    pub fn with_page(mut self, page: u32) -> Self {
42        self.page = Some(page);
43        self
44    }
45    pub fn with_size(mut self, size: u32) -> Self {
46        self.size = Some(size);
47        self
48    }
49    pub fn with_word(mut self, word: impl Into<String>) -> Self {
50        self.word = Some(word.into());
51        self
52    }
53}
54
55/// Document list request (GET /llm-application/open/document)
56pub struct DocumentListRequest {
57    /// Bearer API key
58    pub key: String,
59    url: String,
60    endpoint_config: EndpointConfig,
61    api_base: ApiBase,
62    http_config: Arc<HttpClientConfig>,
63    query: Option<DocumentListQuery>,
64    _body: (),
65}
66
67impl DocumentListRequest {
68    pub fn new(key: String) -> Self {
69        let endpoint_config = EndpointConfig::default();
70        let api_base = ApiBase::LlmApplication;
71        let url = endpoint_config.url(&api_base, paths::DOCUMENT);
72        Self {
73            key,
74            url,
75            endpoint_config,
76            api_base,
77            http_config: Arc::new(HttpClientConfig::default()),
78            query: None,
79            _body: (),
80        }
81    }
82
83    fn rebuild_url(&mut self) {
84        let endpoint = self.endpoint_config.url(&self.api_base, paths::DOCUMENT);
85        let mut params: Vec<(&str, String)> = Vec::new();
86        if let Some(q) = &self.query {
87            params.push(("knowledge_id", q.knowledge_id.clone()));
88            if let Some(page) = q.page.as_ref() {
89                params.push(("page", page.to_string()));
90            }
91            if let Some(size) = q.size.as_ref() {
92                params.push(("size", size.to_string()));
93            }
94            if let Some(word) = q.word.as_ref() {
95                params.push(("word", word.clone()));
96            }
97        }
98        self.url = build_query(&endpoint, params);
99    }
100
101    pub fn with_base_url(mut self, base: impl Into<String>) -> Self {
102        self.api_base = ApiBase::Custom(base.into());
103        self.rebuild_url();
104        self
105    }
106
107    pub fn with_endpoint_config(mut self, endpoint_config: EndpointConfig) -> Self {
108        self.endpoint_config = endpoint_config;
109        self.rebuild_url();
110        self
111    }
112
113    pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
114        self.http_config = Arc::new(config);
115        self
116    }
117
118    /// Apply query by rebuilding internal URL
119    pub fn with_query(mut self, q: DocumentListQuery) -> Self {
120        self.query = Some(q);
121        self.rebuild_url();
122        self
123    }
124
125    /// Validate query, rebuild URL, then send
126    pub async fn send_with_query(
127        mut self,
128        q: &DocumentListQuery,
129    ) -> ZaiResult<DocumentListResponse> {
130        use validator::Validate;
131        q.validate()?;
132        self.query = Some(q.clone());
133        self.rebuild_url();
134        self.send().await
135    }
136
137    /// Send and parse typed response
138    pub async fn send(&self) -> ZaiResult<DocumentListResponse> {
139        let resp = self.get().await?;
140        let parsed = parse_typed_response::<DocumentListResponse>(resp).await?;
141        Ok(parsed)
142    }
143}
144
145impl HttpClient for DocumentListRequest {
146    type Body = ();
147    type ApiUrl = String;
148    type ApiKey = String;
149
150    fn api_url(&self) -> &Self::ApiUrl {
151        &self.url
152    }
153    fn api_key(&self) -> &Self::ApiKey {
154        &self.key
155    }
156    fn body(&self) -> &Self::Body {
157        &self._body
158    }
159
160    fn http_config(&self) -> Arc<HttpClientConfig> {
161        Arc::clone(&self.http_config)
162    }
163}