rain_sdk/api/
reports.rs

1//! Reports API
2//!
3//! This module provides functionality to get tenant reports.
4
5use crate::client::RainClient;
6use crate::error::Result;
7use crate::models::reports::*;
8
9impl RainClient {
10    /// Get a tenant's report
11    ///
12    /// # Arguments
13    ///
14    /// * `year` - Year of the report
15    /// * `month` - Month of the report
16    /// * `day` - Day of the report
17    /// * `params` - Optional query parameters (format)
18    ///
19    /// # Returns
20    ///
21    /// Returns the report as raw bytes (content type depends on format: csv, json, or ssrp).
22    ///
23    /// # Errors
24    ///
25    /// This method can return the following errors:
26    /// - `400` - Invalid request
27    /// - `401` - Invalid authorization
28    /// - `404` - Report not found
29    /// - `500` - Internal server error
30    ///
31    /// # Examples
32    ///
33    /// ```no_run
34    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
35    /// use rain_sdk::models::reports::{GetReportParams, ReportFormat};
36    ///
37    /// # #[cfg(feature = "async")]
38    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
39    /// let config = Config::new(Environment::Dev);
40    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
41    /// let client = RainClient::new(config, auth)?;
42    ///
43    /// let params = GetReportParams {
44    ///     format: Some(ReportFormat::Csv),
45    /// };
46    /// let report = client.get_report("2024", "01", "15", &params).await?;
47    /// # Ok(())
48    /// # }
49    /// ```
50    #[cfg(feature = "async")]
51    pub async fn get_report(
52        &self,
53        year: &str,
54        month: &str,
55        day: &str,
56        params: &GetReportParams,
57    ) -> Result<Vec<u8>> {
58        let base_url = self.base_url();
59        let mut url = base_url.clone();
60        url.path_segments_mut()
61            .map_err(|_| crate::error::RainError::Other(anyhow::anyhow!("Cannot be a base URL")))?
62            .pop_if_empty()
63            .push("issuing")
64            .push("reports")
65            .push(year)
66            .push(month)
67            .push(day);
68
69        let query_string = serde_urlencoded::to_string(params)?;
70        let full_path = if query_string.is_empty() {
71            format!("/reports/{year}/{month}/{day}")
72        } else {
73            format!("/reports/{year}/{month}/{day}?{query_string}")
74        };
75        self.get_bytes(&full_path).await
76    }
77
78    // ============================================================================
79    // Blocking Methods
80    // ============================================================================
81
82    /// Get a tenant's report (blocking)
83    #[cfg(feature = "sync")]
84    pub fn get_report_blocking(
85        &self,
86        year: &str,
87        month: &str,
88        day: &str,
89        params: &GetReportParams,
90    ) -> Result<Vec<u8>> {
91        let query_string = serde_urlencoded::to_string(params)?;
92        let full_path = if query_string.is_empty() {
93            format!("/reports/{year}/{month}/{day}")
94        } else {
95            format!("/reports/{year}/{month}/{day}?{query_string}")
96        };
97        self.get_bytes_blocking(&full_path)
98    }
99}