rain_sdk/api/
transactions.rs

1//! Transactions API
2//!
3//! This module provides functionality to manage transactions.
4
5use crate::client::RainClient;
6use crate::error::Result;
7use crate::models::transactions::*;
8use uuid::Uuid;
9
10impl RainClient {
11    /// Get all transactions
12    ///
13    /// # Arguments
14    ///
15    /// * `params` - Query parameters to filter transactions
16    ///
17    /// # Returns
18    ///
19    /// Returns a [`Vec<Transaction>`] containing the list of transactions.
20    ///
21    /// # Errors
22    ///
23    /// This method can return the following errors:
24    /// - `401` - Invalid authorization
25    /// - `500` - Internal server error
26    #[cfg(feature = "async")]
27    pub async fn list_transactions(
28        &self,
29        params: &ListTransactionsParams,
30    ) -> Result<Vec<Transaction>> {
31        let path = "/transactions";
32        let query_string = serde_urlencoded::to_string(params)?;
33        let full_path = if query_string.is_empty() {
34            path.to_string()
35        } else {
36            format!("{path}?{query_string}")
37        };
38        self.get(&full_path).await
39    }
40
41    /// Get a transaction by its id
42    ///
43    /// # Arguments
44    ///
45    /// * `transaction_id` - The unique identifier of the transaction
46    ///
47    /// # Returns
48    ///
49    /// Returns a [`Transaction`] containing the transaction information.
50    ///
51    /// # Errors
52    ///
53    /// This method can return the following errors:
54    /// - `401` - Invalid authorization
55    /// - `404` - Transaction not found
56    /// - `500` - Internal server error
57    #[cfg(feature = "async")]
58    pub async fn get_transaction(&self, transaction_id: &Uuid) -> Result<Transaction> {
59        let path = format!("/transactions/{transaction_id}");
60        self.get(&path).await
61    }
62
63    /// Update a transaction
64    ///
65    /// # Arguments
66    ///
67    /// * `transaction_id` - The unique identifier of the transaction
68    /// * `request` - The update request
69    ///
70    /// # Returns
71    ///
72    /// Returns success (204 No Content) with no response body.
73    ///
74    /// # Errors
75    ///
76    /// This method can return the following errors:
77    /// - `400` - Invalid request
78    /// - `401` - Invalid authorization
79    /// - `404` - Transaction not found
80    /// - `500` - Internal server error
81    #[cfg(feature = "async")]
82    pub async fn update_transaction(
83        &self,
84        transaction_id: &Uuid,
85        request: &UpdateTransactionRequest,
86    ) -> Result<()> {
87        let path = format!("/transactions/{transaction_id}");
88        let _: serde_json::Value = self.patch(&path, request).await?;
89        Ok(())
90    }
91
92    /// Get a transaction's receipt
93    ///
94    /// # Arguments
95    ///
96    /// * `transaction_id` - The unique identifier of the transaction
97    ///
98    /// # Returns
99    ///
100    /// Returns the receipt as raw bytes (application/octet-stream).
101    #[cfg(feature = "async")]
102    pub async fn get_transaction_receipt(&self, transaction_id: &Uuid) -> Result<Vec<u8>> {
103        let path = format!("/transactions/{transaction_id}/receipt");
104        self.get_bytes(&path).await
105    }
106
107    /// Upload a transaction's receipt
108    ///
109    /// # Arguments
110    ///
111    /// * `transaction_id` - The unique identifier of the transaction
112    /// * `request` - The receipt upload request
113    ///
114    /// # Returns
115    ///
116    /// Returns success (204 No Content) with no response body.
117    #[cfg(feature = "async")]
118    pub async fn upload_transaction_receipt(
119        &self,
120        transaction_id: &Uuid,
121        request: &UploadReceiptRequest,
122    ) -> Result<()> {
123        let path = format!("/transactions/{transaction_id}/receipt");
124
125        use reqwest::multipart::{Form, Part};
126        let form = Form::new().part(
127            "receipt",
128            Part::bytes(request.receipt.clone()).file_name(request.file_name.clone()),
129        );
130
131        self.put_multipart_no_content(&path, form).await
132    }
133
134    // ============================================================================
135    // Blocking Methods
136    // ============================================================================
137
138    /// Get all transactions (blocking)
139    #[cfg(feature = "sync")]
140    pub fn list_transactions_blocking(
141        &self,
142        params: &ListTransactionsParams,
143    ) -> Result<Vec<Transaction>> {
144        let path = "/transactions";
145        let query_string = serde_urlencoded::to_string(params)?;
146        let full_path = if query_string.is_empty() {
147            path.to_string()
148        } else {
149            format!("{path}?{query_string}")
150        };
151        self.get_blocking(&full_path)
152    }
153
154    /// Get a transaction by its id (blocking)
155    #[cfg(feature = "sync")]
156    pub fn get_transaction_blocking(&self, transaction_id: &Uuid) -> Result<Transaction> {
157        let path = format!("/transactions/{transaction_id}");
158        self.get_blocking(&path)
159    }
160
161    /// Update a transaction (blocking)
162    #[cfg(feature = "sync")]
163    pub fn update_transaction_blocking(
164        &self,
165        transaction_id: &Uuid,
166        request: &UpdateTransactionRequest,
167    ) -> Result<()> {
168        let path = format!("/transactions/{transaction_id}");
169        let _: serde_json::Value = self.patch_blocking(&path, request)?;
170        Ok(())
171    }
172
173    /// Get a transaction's receipt (blocking)
174    #[cfg(feature = "sync")]
175    pub fn get_transaction_receipt_blocking(&self, transaction_id: &Uuid) -> Result<Vec<u8>> {
176        let path = format!("/transactions/{transaction_id}/receipt");
177        self.get_bytes_blocking(&path)
178    }
179
180    /// Upload a transaction's receipt (blocking)
181    #[cfg(feature = "sync")]
182    pub fn upload_transaction_receipt_blocking(
183        &self,
184        transaction_id: &Uuid,
185        request: &UploadReceiptRequest,
186    ) -> Result<()> {
187        let path = format!("/transactions/{transaction_id}/receipt");
188
189        use reqwest::blocking::multipart::{Form, Part};
190        let form = Form::new().part(
191            "receipt",
192            Part::bytes(request.receipt.clone()).file_name(request.file_name.clone()),
193        );
194
195        self.put_multipart_blocking_no_content(&path, form)
196    }
197}