rain_sdk/api/
users.rs

1//! Users API
2//!
3//! This module provides functionality to manage users.
4
5use crate::client::RainClient;
6use crate::error::Result;
7use crate::models::charges::*;
8use crate::models::users::*;
9use uuid::Uuid;
10
11impl RainClient {
12    /// Get all users
13    ///
14    /// # Arguments
15    ///
16    /// * `params` - Query parameters for filtering users
17    ///
18    /// # Returns
19    ///
20    /// Returns a [`Vec<User>`] containing the list of users.
21    ///
22    /// # Errors
23    ///
24    /// This method can return the following errors:
25    /// - `401` - Invalid authorization
26    /// - `500` - Internal server error
27    ///
28    /// # Examples
29    ///
30    /// ```no_run
31    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
32    /// use rain_sdk::models::users::ListUsersParams;
33    /// use uuid::Uuid;
34    ///
35    /// # #[cfg(feature = "async")]
36    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
37    /// let config = Config::new(Environment::Dev);
38    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
39    /// let client = RainClient::new(config, auth)?;
40    ///
41    /// let params = ListUsersParams {
42    ///     company_id: None,
43    ///     cursor: None,
44    ///     limit: Some(20),
45    /// };
46    /// let users = client.list_users(&params).await?;
47    /// # Ok(())
48    /// # }
49    /// ```
50    #[cfg(feature = "async")]
51    pub async fn list_users(&self, params: &ListUsersParams) -> Result<Vec<User>> {
52        let mut path = "/users".to_string();
53        let mut query_parts = Vec::new();
54
55        if let Some(ref company_id) = params.company_id {
56            query_parts.push(format!("companyId={company_id}"));
57        }
58        if let Some(ref cursor) = params.cursor {
59            query_parts.push(format!("cursor={cursor}"));
60        }
61        if let Some(limit) = params.limit {
62            query_parts.push(format!("limit={limit}"));
63        }
64
65        if !query_parts.is_empty() {
66            path.push('?');
67            path.push_str(&query_parts.join("&"));
68        }
69
70        self.get(&path).await
71    }
72
73    /// Create an authorized user
74    ///
75    /// # Arguments
76    ///
77    /// * `request` - The user creation request
78    ///
79    /// # Returns
80    ///
81    /// Returns a [`User`] containing the created user information.
82    ///
83    /// # Errors
84    ///
85    /// This method can return the following errors:
86    /// - `400` - Invalid request
87    /// - `401` - Invalid authorization
88    /// - `500` - Internal server error
89    ///
90    /// # Examples
91    ///
92    /// ```no_run
93    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
94    /// use rain_sdk::models::users::CreateUserRequest;
95    ///
96    /// # #[cfg(feature = "async")]
97    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
98    /// let config = Config::new(Environment::Dev);
99    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
100    /// let client = RainClient::new(config, auth)?;
101    ///
102    /// let request = CreateUserRequest {
103    ///     first_name: "John".to_string(),
104    ///     last_name: "Doe".to_string(),
105    ///     email: "john@example.com".to_string(),
106    ///     wallet_address: None,
107    ///     solana_address: None,
108    ///     address: None,
109    ///     phone_country_code: None,
110    ///     phone_number: None,
111    /// };
112    /// let user = client.create_user(&request).await?;
113    /// # Ok(())
114    /// # }
115    /// ```
116    #[cfg(feature = "async")]
117    pub async fn create_user(&self, request: &CreateUserRequest) -> Result<User> {
118        let path = "/users";
119        self.post(path, request).await
120    }
121
122    /// Get a user by its ID
123    ///
124    /// # Arguments
125    ///
126    /// * `user_id` - The unique identifier of the user
127    ///
128    /// # Returns
129    ///
130    /// Returns a [`User`] containing the user information.
131    ///
132    /// # Errors
133    ///
134    /// This method can return the following errors:
135    /// - `401` - Invalid authorization
136    /// - `404` - User not found
137    /// - `500` - Internal server error
138    ///
139    /// # Examples
140    ///
141    /// ```no_run
142    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
143    /// use uuid::Uuid;
144    ///
145    /// # #[cfg(feature = "async")]
146    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
147    /// let config = Config::new(Environment::Dev);
148    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
149    /// let client = RainClient::new(config, auth)?;
150    ///
151    /// let user_id = Uuid::new_v4();
152    /// let user = client.get_user(&user_id).await?;
153    /// # Ok(())
154    /// # }
155    /// ```
156    #[cfg(feature = "async")]
157    pub async fn get_user(&self, user_id: &Uuid) -> Result<User> {
158        let path = format!("/users/{user_id}");
159        self.get(&path).await
160    }
161
162    /// Delete a user
163    ///
164    /// # Arguments
165    ///
166    /// * `user_id` - The unique identifier of the user
167    ///
168    /// # Returns
169    ///
170    /// Returns success (204 No Content).
171    ///
172    /// # Errors
173    ///
174    /// This method can return the following errors:
175    /// - `401` - Invalid authorization
176    /// - `404` - User not found
177    /// - `500` - Internal server error
178    ///
179    /// # Examples
180    ///
181    /// ```no_run
182    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
183    /// use uuid::Uuid;
184    ///
185    /// # #[cfg(feature = "async")]
186    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
187    /// let config = Config::new(Environment::Dev);
188    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
189    /// let client = RainClient::new(config, auth)?;
190    ///
191    /// let user_id = Uuid::new_v4();
192    /// client.delete_user(&user_id).await?;
193    /// # Ok(())
194    /// # }
195    /// ```
196    #[cfg(feature = "async")]
197    pub async fn delete_user(&self, user_id: &Uuid) -> Result<()> {
198        let path = format!("/users/{user_id}");
199        self.delete(&path).await
200    }
201
202    /// Update a user
203    ///
204    /// # Arguments
205    ///
206    /// * `user_id` - The unique identifier of the user
207    /// * `request` - The update request
208    ///
209    /// # Returns
210    ///
211    /// Returns a [`User`] containing the updated user information.
212    ///
213    /// # Errors
214    ///
215    /// This method can return the following errors:
216    /// - `400` - Invalid request
217    /// - `401` - Invalid authorization
218    /// - `404` - User not found
219    /// - `423` - User address is locked
220    /// - `500` - Internal server error
221    ///
222    /// # Examples
223    ///
224    /// ```no_run
225    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
226    /// use rain_sdk::models::users::UpdateUserRequest;
227    /// use uuid::Uuid;
228    ///
229    /// # #[cfg(feature = "async")]
230    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
231    /// let config = Config::new(Environment::Dev);
232    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
233    /// let client = RainClient::new(config, auth)?;
234    ///
235    /// let user_id = Uuid::new_v4();
236    /// let request = UpdateUserRequest {
237    ///     first_name: Some("Jane".to_string()),
238    ///     last_name: None,
239    ///     email: None,
240    ///     is_active: None,
241    ///     is_terms_of_service_accepted: None,
242    ///     address: None,
243    ///     phone_country_code: None,
244    ///     phone_number: None,
245    ///     wallet_address: None,
246    ///     solana_address: None,
247    ///     tron_address: None,
248    ///     stellar_address: None,
249    /// };
250    /// let user = client.update_user(&user_id, &request).await?;
251    /// # Ok(())
252    /// # }
253    /// ```
254    #[cfg(feature = "async")]
255    pub async fn update_user(&self, user_id: &Uuid, request: &UpdateUserRequest) -> Result<User> {
256        let path = format!("/users/{user_id}");
257        self.patch(&path, request).await
258    }
259
260    /// Charge a user a custom fee
261    ///
262    /// # Arguments
263    ///
264    /// * `user_id` - The unique identifier of the user
265    /// * `request` - The charge request
266    ///
267    /// # Returns
268    ///
269    /// Returns a [`Charge`] containing the created charge information.
270    ///
271    /// # Errors
272    ///
273    /// This method can return the following errors:
274    /// - `400` - Invalid request
275    /// - `401` - Invalid authorization
276    /// - `404` - User not found
277    /// - `500` - Internal server error
278    ///
279    /// # Examples
280    ///
281    /// ```no_run
282    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
283    /// use rain_sdk::models::charges::CreateChargeRequest;
284    /// use uuid::Uuid;
285    ///
286    /// # #[cfg(feature = "async")]
287    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
288    /// let config = Config::new(Environment::Dev);
289    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
290    /// let client = RainClient::new(config, auth)?;
291    ///
292    /// let user_id = Uuid::new_v4();
293    /// let request = CreateChargeRequest {
294    ///     amount: 500, // $5.00 in cents
295    ///     description: "Custom fee".to_string(),
296    /// };
297    /// let charge = client.charge_user(&user_id, &request).await?;
298    /// # Ok(())
299    /// # }
300    /// ```
301    #[cfg(feature = "async")]
302    pub async fn charge_user(
303        &self,
304        user_id: &Uuid,
305        request: &CreateChargeRequest,
306    ) -> Result<Charge> {
307        let path = format!("/users/{user_id}/charges");
308        self.post(&path, request).await
309    }
310
311    // ============================================================================
312    // Blocking Methods
313    // ============================================================================
314
315    /// Get all users (blocking)
316    #[cfg(feature = "sync")]
317    pub fn list_users_blocking(&self, params: &ListUsersParams) -> Result<Vec<User>> {
318        let mut path = "/users".to_string();
319        let mut query_parts = Vec::new();
320
321        if let Some(ref company_id) = params.company_id {
322            query_parts.push(format!("companyId={company_id}"));
323        }
324        if let Some(ref cursor) = params.cursor {
325            query_parts.push(format!("cursor={cursor}"));
326        }
327        if let Some(limit) = params.limit {
328            query_parts.push(format!("limit={limit}"));
329        }
330
331        if !query_parts.is_empty() {
332            path.push('?');
333            path.push_str(&query_parts.join("&"));
334        }
335
336        self.get_blocking(&path)
337    }
338
339    /// Create an authorized user (blocking)
340    #[cfg(feature = "sync")]
341    pub fn create_user_blocking(&self, request: &CreateUserRequest) -> Result<User> {
342        let path = "/users";
343        self.post_blocking(path, request)
344    }
345
346    /// Get a user by its ID (blocking)
347    #[cfg(feature = "sync")]
348    pub fn get_user_blocking(&self, user_id: &Uuid) -> Result<User> {
349        let path = format!("/users/{user_id}");
350        self.get_blocking(&path)
351    }
352
353    /// Delete a user (blocking)
354    #[cfg(feature = "sync")]
355    pub fn delete_user_blocking(&self, user_id: &Uuid) -> Result<()> {
356        let path = format!("/users/{user_id}");
357        self.delete_blocking(&path)
358    }
359
360    /// Update a user (blocking)
361    #[cfg(feature = "sync")]
362    pub fn update_user_blocking(
363        &self,
364        user_id: &Uuid,
365        request: &UpdateUserRequest,
366    ) -> Result<User> {
367        let path = format!("/users/{user_id}");
368        self.patch_blocking(&path, request)
369    }
370
371    /// Charge a user a custom fee (blocking)
372    #[cfg(feature = "sync")]
373    pub fn charge_user_blocking(
374        &self,
375        user_id: &Uuid,
376        request: &CreateChargeRequest,
377    ) -> Result<Charge> {
378        let path = format!("/users/{user_id}/charges");
379        self.post_blocking(&path, request)
380    }
381}