Skip to main content

zai_rs/knowledge/
document_list.rs

1use super::types::DocumentListResponse;
2use crate::ZaiResult;
3use crate::client::ZaiClient;
4
5/// Query parameters for listing documents under a knowledge base
6#[derive(Debug, Clone, serde::Serialize, validator::Validate, Default)]
7#[allow(clippy::new_without_default)]
8pub struct DocumentListQuery {
9    /// Knowledge base id (required)
10    #[validate(length(min = 1))]
11    pub knowledge_id: String,
12    /// Page index (default 1)
13    #[serde(skip_serializing_if = "Option::is_none")]
14    #[validate(range(min = 1))]
15    pub page: Option<u32>,
16    /// Page size (default 10)
17    #[serde(skip_serializing_if = "Option::is_none")]
18    #[validate(range(min = 1))]
19    pub size: Option<u32>,
20    /// Document name filter
21    #[serde(skip_serializing_if = "Option::is_none")]
22    #[validate(length(min = 1))]
23    pub word: Option<String>,
24}
25
26impl DocumentListQuery {
27    /// Create a new query for the given knowledge base id (page 1, size 10).
28    pub fn new(knowledge_id: impl Into<String>) -> Self {
29        Self {
30            knowledge_id: knowledge_id.into(),
31            page: Some(1),
32            size: Some(10),
33            word: None,
34        }
35    }
36    /// Set the page index (1-based).
37    pub fn with_page(mut self, page: u32) -> Self {
38        self.page = Some(page);
39        self
40    }
41    /// Set the page size.
42    pub fn with_size(mut self, size: u32) -> Self {
43        self.size = Some(size);
44        self
45    }
46    /// Filter by document name.
47    pub fn with_word(mut self, word: impl Into<String>) -> Self {
48        self.word = Some(word.into());
49        self
50    }
51
52    /// Build the `(&str, String)` query pairs (in stable order) used to form
53    /// the request URL.
54    fn pairs(&self) -> Vec<(&'static str, String)> {
55        let mut params: Vec<(&'static str, String)> = Vec::new();
56        params.push(("knowledge_id", self.knowledge_id.clone()));
57        if let Some(page) = self.page.as_ref() {
58            params.push(("page", page.to_string()));
59        }
60        if let Some(size) = self.size.as_ref() {
61            params.push(("size", size.to_string()));
62        }
63        if let Some(word) = self.word.as_ref() {
64            params.push(("word", word.clone()));
65        }
66        params
67    }
68}
69
70/// Document list request (GET /llm-application/open/document)
71///
72/// Credentials and transport live on the [`ZaiClient`], passed to
73/// [`send_via`](Self::send_via).
74#[allow(clippy::new_without_default)]
75pub struct DocumentListRequest {
76    query: Option<DocumentListQuery>,
77}
78
79impl DocumentListRequest {
80    /// Create a new document-list request (no query set yet).
81    #[allow(clippy::new_without_default)]
82    pub fn new() -> Self {
83        Self { query: None }
84    }
85
86    /// Apply a query (replaces the current one).
87    pub fn with_query(mut self, q: DocumentListQuery) -> Self {
88        self.query = Some(q);
89        self
90    }
91
92    /// Send via a [`ZaiClient`] and parse the typed response. Requires a query
93    /// to have been set via [`with_query`](Self::with_query).
94    pub async fn send_via(&self, client: &ZaiClient) -> ZaiResult<DocumentListResponse> {
95        let q = self
96            .query
97            .as_ref()
98            .ok_or_else(|| crate::ZaiError::ApiError {
99                code: crate::client::error::codes::SDK_VALIDATION,
100                message: "document list requires a knowledge_id; call with_query first".to_string(),
101            })?;
102        let params = q.pairs();
103        let route = crate::client::routes::DOCUMENTS_LIST;
104        let url = client.endpoints().resolve_route_with_query(
105            route,
106            &[],
107            &params
108                .iter()
109                .map(|(k, v)| (*k, v.as_str()))
110                .collect::<Vec<_>>(),
111        )?;
112        client
113            .send_empty::<DocumentListResponse>(route.method(), url)
114            .await
115    }
116
117    /// Validate the query then send via a [`ZaiClient`] and parse the typed
118    /// response.
119    pub async fn send_via_with_query(
120        mut self,
121        client: &ZaiClient,
122        q: &DocumentListQuery,
123    ) -> ZaiResult<DocumentListResponse> {
124        use validator::Validate;
125        q.validate()?;
126        self.query = Some(q.clone());
127        self.send_via(client).await
128    }
129}