Skip to main content

zai_rs/tool/file_parser_create/
data.rs

1//! # File Parser Creation API
2//!
3//! This module provides the file parser creation client for creating file
4//! parsing tasks.
5
6use std::path::Path;
7
8use serde_json;
9
10use super::{request::*, response::*};
11use crate::ZaiResult;
12
13/// File parser creation client.
14///
15/// This client provides functionality to create file parsing tasks,
16/// supporting multiple file formats and parsing tools.
17///
18/// ## Examples
19///
20/// ```rust,ignore
21/// use zai_rs::tool::file_parser_create::{FileParserCreateRequest, ToolType, FileType};
22/// use std::path::Path;
23///
24/// let api_key = "your-api-key".to_string();
25/// let file_path = Path::new("document.pdf");
26///
27/// let request = FileParserCreateRequest::new(
28///     api_key,
29///     file_path,
30///     ToolType::Lite,
31///     FileType::PDF,
32/// )?;
33/// ```
34pub struct FileParserCreateRequest {
35    /// API key for authentication
36    pub key: String,
37    /// Path to the file to parse
38    pub file_path: std::path::PathBuf,
39    /// Parsing tool type to use
40    pub tool_type: ToolType,
41    /// File type to parse
42    pub file_type: FileType,
43}
44
45impl FileParserCreateRequest {
46    /// Creates a new file parser creation request.
47    ///
48    /// ## Arguments
49    ///
50    /// * `key` - API key for authentication
51    /// * `file_path` - Path to the file to parse
52    /// * `tool_type` - Type of parsing tool to use
53    /// * `file_type` - Type of file to parse
54    ///
55    /// ## Returns
56    ///
57    /// A new `FileParserCreateRequest` instance or an error if validation
58    /// fails.
59    pub fn new(
60        key: String,
61        file_path: &Path,
62        tool_type: ToolType,
63        file_type: FileType,
64    ) -> crate::ZaiResult<Self> {
65        // Validate that file exists
66        if !file_path.exists() {
67            return Err(crate::client::error::ZaiError::FileError {
68                code: 0,
69                message: format!("File does not exist: {}", file_path.display()),
70            });
71        }
72
73        // Validate that file type is supported by tool
74        if !file_type.is_supported_by(&tool_type) {
75            return Err(crate::client::error::ZaiError::ApiError {
76                code: 1200,
77                message: format!(
78                    "File type {:?} is not supported by tool type {:?}",
79                    file_type, tool_type
80                ),
81            });
82        }
83
84        Ok(Self {
85            key,
86            file_path: file_path.to_path_buf(),
87            tool_type,
88            file_type,
89        })
90    }
91
92    /// Creates a new file parser creation request with automatic file type
93    /// detection.
94    ///
95    /// ## Arguments
96    ///
97    /// * `key` - API key for authentication
98    /// * `file_path` - Path to the file to parse
99    /// * `tool_type` - Type of parsing tool to use
100    ///
101    /// ## Returns
102    ///
103    /// A new `FileParserCreateRequest` instance or an error if validation
104    /// fails.
105    pub fn new_with_auto_type(
106        key: String,
107        file_path: &Path,
108        tool_type: ToolType,
109    ) -> crate::ZaiResult<Self> {
110        let file_type = FileType::from_path(file_path).ok_or_else(|| {
111            crate::client::error::ZaiError::FileError {
112                code: 0,
113                message: format!(
114                    "Could not determine file type from path: {}",
115                    file_path.display()
116                ),
117            }
118        })?;
119
120        Self::new(key, file_path, tool_type, file_type)
121    }
122
123    /// Sends the file parser task creation request.
124    ///
125    /// ## Returns
126    ///
127    /// A `FileParserCreateResponse` containing the task ID and status.
128    pub async fn send(&self) -> ZaiResult<FileParserCreateResponse> {
129        println!("📤 Creating file parser task...");
130        println!("📁 File: {}", self.file_path.display());
131        println!("🛠️  Tool type: {:?}", self.tool_type);
132        println!("📄 File type: {:?}", self.file_type);
133        println!("🔑 API key: {}...", &self.key[..10]);
134
135        let file_bytes = tokio::fs::read(&self.file_path).await?;
136        let file_name = self
137            .file_path
138            .file_name()
139            .unwrap_or_default()
140            .to_string_lossy()
141            .to_string();
142
143        println!("📊 File size: {} bytes", file_bytes.len());
144        println!("📝 File name: {}", file_name);
145
146        let file_part = reqwest::multipart::Part::bytes(file_bytes)
147            .file_name(file_name)
148            .mime_str("application/octet-stream")?;
149
150        let form = reqwest::multipart::Form::new()
151            .part("file", file_part)
152            .text("tool_type", format!("{:?}", self.tool_type).to_lowercase())
153            .text("file_type", format!("{:?}", self.file_type));
154
155        let client = reqwest::Client::new();
156        println!("🌐 Sending request to: https://open.bigmodel.cn/api/paas/v4/files/parser/create");
157
158        let response = client
159            .post("https://open.bigmodel.cn/api/paas/v4/files/parser/create")
160            .bearer_auth(&self.key)
161            .multipart(form)
162            .send()
163            .await?;
164
165        let status = response.status();
166        println!("📡 Response status: {}", status);
167
168        let response_text = response.text().await.unwrap_or_default();
169        println!("📄 Raw response: {}", response_text);
170
171        if !status.is_success() {
172            return Err(crate::client::error::ZaiError::HttpError {
173                status: status.as_u16(),
174                message: response_text,
175            });
176        }
177
178        let create_response: FileParserCreateResponse = serde_json::from_str(&response_text)
179            .map_err(|e| crate::client::error::ZaiError::ApiError {
180                code: 1200,
181                message: format!(
182                    "Failed to decode response: {} - Response was: {}",
183                    e, response_text
184                ),
185            })?;
186
187        println!("✅ Task created successfully: {:?}", create_response);
188
189        if !create_response.is_success() {
190            return Err(crate::client::error::ZaiError::ApiError {
191                code: 0,
192                message: format!("Task creation failed: {}", create_response.message),
193            });
194        }
195
196        Ok(create_response)
197    }
198}