1use reqwest::multipart;
2use serde::{Deserialize, Serialize};
3
4use crate::{MistralClient, MistralError, MistralApiError};
5
6#[derive(Serialize, Deserialize, Debug)]
7pub struct FileData {
8 pub id: String,
9 object: String,
10 bytes: u64,
11 created_at: u64,
12 filename: String,
13 purpose: String,
14 sample_type: String,
15 num_lines: Option<u64>,
16 source: String,
17}
18
19#[derive(Serialize, Deserialize, Debug)]
20pub struct SignedUrl {
21 pub url: String,
22}
23
24pub struct FileClient<'a> {
25 mistral_client: &'a MistralClient,
26 files_path: String,
27}
28
29impl<'a> FileClient<'a> {
30 pub fn new(mistral_client: &'a MistralClient) -> Self {
31 FileClient {
32 mistral_client,
33 files_path: "files".to_string(),
34 }
35 }
36
37 pub async fn upload_file(&self, file_data: Vec<u8>) -> Result<FileData, MistralError> {
38 let part = multipart::Part::bytes(file_data).file_name("uploaded_file.pdf");
39 let form = multipart::Form::new()
40 .text("purpose", "ocr")
41 .part("file", part);
42
43 let response = self
44 .mistral_client
45 .client
46 .post(&format!("{}/{}", self.mistral_client.base_url, self.files_path))
47 .bearer_auth(&self.mistral_client.api_key)
48 .multipart(form)
49 .send()
50 .await
51 .map_err(MistralError::Network)?;
52
53 let status = response.status();
54 let response_text = response.text().await.map_err(MistralError::Network)?;
55
56 if !status.is_success() {
57 return match serde_json::from_str::<MistralApiError>(&response_text) {
58 Ok(mut err) => {
59 err.description = crate::error_description(err.code).to_string();
60 Err(MistralError::Api(err))
61 },
62 Err(_) => Err(MistralError::Http(status)),
63 };
64 }
65
66 serde_json::from_str(&response_text).map_err(MistralError::Parse)
67 }
68
69 pub async fn get_signed_url(&self, file_id: &str) -> Result<SignedUrl, MistralError> {
70 let call_url = format!(
71 "{}/{}/{}/url?expiry=24",
72 self.mistral_client.base_url, self.files_path, file_id
73 );
74
75 let response = self
76 .mistral_client
77 .client
78 .get(call_url)
79 .bearer_auth(&self.mistral_client.api_key)
80 .send()
81 .await
82 .map_err(MistralError::Network)?;
83
84 let status = response.status();
85 let response_text = response.text().await.map_err(MistralError::Network)?;
86
87 if !status.is_success() {
88 return match serde_json::from_str::<MistralApiError>(&response_text) {
89 Ok(mut err) => {
90 err.description = crate::error_description(err.code).to_string();
91 Err(MistralError::Api(err))
92 },
93 Err(_) => Err(MistralError::Http(status)),
94 };
95 }
96
97 serde_json::from_str(&response_text).map_err(MistralError::Parse)
98 }
99}