Skip to main content

zai_rs/tool/file_parser_result/
data.rs

1//! # File Parser Result API
2//!
3//! This module provides the file parser result client for retrieving file
4//! parsing results.
5
6use serde_json;
7
8use super::{request::*, response::*};
9use crate::ZaiResult;
10
11/// File parser result client.
12///
13/// This client provides functionality to retrieve file parsing results,
14/// supporting multiple result formats and asynchronous task monitoring.
15///
16/// ## Examples
17///
18/// ```rust,ignore
19/// use zai_rs::tool::file_parser_result::{FileParserResultRequest, FormatType};
20///
21/// let api_key = "your-api-key".to_string();
22/// let task_id = "task_123456789";
23///
24/// let request = FileParserResultRequest::new(api_key, task_id);
25///
26/// let response = request.get_result(FormatType::Text).await?;
27/// if let Some(content) = response.content() {
28///     println!("Parsed content: {}", content);
29/// }
30/// ```
31pub struct FileParserResultRequest {
32    /// API key for authentication
33    pub key: String,
34    /// Task ID for the parsing job
35    pub task_id: String,
36}
37
38impl FileParserResultRequest {
39    /// Creates a new file parser result request.
40    ///
41    /// ## Arguments
42    ///
43    /// * `key` - API key for authentication
44    /// * `task_id` - ID of the parsing task
45    ///
46    /// ## Returns
47    ///
48    /// A new `FileParserResultRequest` instance.
49    pub fn new(key: String, task_id: impl Into<String>) -> Self {
50        Self {
51            key,
52            task_id: task_id.into(),
53        }
54    }
55
56    /// Gets the parsing result for the given format type.
57    ///
58    /// ## Arguments
59    ///
60    /// * `format_type` - Format type for the result
61    ///
62    /// ## Returns
63    ///
64    /// A `FileParserResultResponse` containing the parsing result.
65    pub async fn get_result(&self, format_type: FormatType) -> ZaiResult<FileParserResultResponse> {
66        let url = format!(
67            "https://open.bigmodel.cn/api/paas/v4/files/parser/result/{}/{}",
68            self.task_id, format_type
69        );
70
71        println!("📤 Sending request to: {}", url);
72        println!("🔑 Using API key: {}...", &self.key[..10]);
73
74        let client = reqwest::Client::new();
75        let response = client.get(&url).bearer_auth(&self.key).send().await?;
76
77        let status = response.status();
78        println!("📡 Response status: {}", status);
79
80        if !status.is_success() {
81            let error_text = response.text().await.unwrap_or_default();
82            println!("❌ Error response: {}", error_text);
83            return Err(crate::client::error::ZaiError::HttpError {
84                status: status.as_u16(),
85                message: error_text,
86            });
87        }
88
89        let response_body = response.text().await?;
90        println!("📄 Raw response body: {}", response_body);
91
92        let result_response: FileParserResultResponse = serde_json::from_str(&response_body)?;
93        println!("✅ Parsed response: {:?}", result_response);
94        Ok(result_response)
95    }
96
97    /// Polls for the result until it's completed or timeout is reached.
98    ///
99    /// ## Arguments
100    ///
101    /// * `format_type` - Format type for the result
102    /// * `timeout_seconds` - Maximum time to wait for result
103    /// * `poll_interval_seconds` - Interval between status checks
104    ///
105    /// ## Returns
106    ///
107    /// A `FileParserResultResponse` containing the parsing result.
108    pub async fn wait_for_result(
109        &self,
110        format_type: FormatType,
111        timeout_seconds: u64,
112        poll_interval_seconds: u64,
113    ) -> ZaiResult<FileParserResultResponse> {
114        println!(
115            "⏳ Starting polling for result (timeout: {}s, interval: {}s)",
116            timeout_seconds, poll_interval_seconds
117        );
118        let start_time = std::time::Instant::now();
119
120        loop {
121            println!("⏰ Checking result status...");
122            let result = self.get_result(format_type.clone()).await?;
123
124            match result.status {
125                ParserStatus::Succeeded => {
126                    println!("🎉 Parsing completed successfully!");
127                    return Ok(result);
128                },
129                ParserStatus::Failed => {
130                    println!("💥 Parsing failed: {}", result.message);
131                    return Err(crate::client::error::ZaiError::ApiError {
132                        code: 0,
133                        message: format!("Parsing failed: {}", result.message),
134                    });
135                },
136                ParserStatus::Processing => {
137                    let elapsed = start_time.elapsed().as_secs();
138                    println!("⏳ Still processing... ({}s elapsed)", elapsed);
139                    if elapsed > timeout_seconds {
140                        println!("⏰ Timeout reached!");
141                        return Err(crate::client::error::ZaiError::RateLimitError {
142                            code: 0,
143                            message: "Timeout waiting for parsing result".to_string(),
144                        });
145                    }
146                    println!(
147                        "⏱️  Waiting {} seconds before next check...",
148                        poll_interval_seconds
149                    );
150                    tokio::time::sleep(tokio::time::Duration::from_secs(poll_interval_seconds))
151                        .await;
152                },
153            }
154        }
155    }
156
157    /// Gets both text and download link results in a single request.
158    ///
159    /// ## Returns
160    ///
161    /// A tuple containing text result and download link result.
162    pub async fn get_all_results(
163        &self,
164    ) -> ZaiResult<(FileParserResultResponse, FileParserResultResponse)> {
165        let text_result = self.get_result(FormatType::Text).await?;
166        let download_result = self.get_result(FormatType::DownloadLink).await?;
167        Ok((text_result, download_result))
168    }
169}