reso_client/
replication.rs

1// src/replication.rs
2
3//! Replication endpoint response types
4
5use serde_json::Value as JsonValue;
6
7/// Response from a replication endpoint query
8///
9/// The replication endpoint returns records along with a `next` link in the
10/// response headers for pagination through large datasets.
11///
12/// # Example
13///
14/// ```no_run
15/// # use reso_client::{ResoClient, ReplicationQueryBuilder};
16/// # async fn example(client: &ResoClient) -> Result<(), Box<dyn std::error::Error>> {
17/// let query = ReplicationQueryBuilder::new("Property")
18///     .top(2000)
19///     .build()?;
20///
21/// let response = client.execute_replication(&query).await?;
22///
23/// println!("Retrieved {} records", response.record_count);
24///
25/// // Continue with next link if available
26/// if let Some(next_link) = response.next_link {
27///     let next_response = client.execute_next_link(&next_link).await?;
28///     println!("Retrieved {} more records", next_response.record_count);
29/// }
30/// # Ok(())
31/// # }
32/// ```
33#[derive(Debug, Clone)]
34pub struct ReplicationResponse {
35    /// The array of records returned by the query
36    pub records: Vec<JsonValue>,
37
38    /// The next link URL from response headers for pagination
39    ///
40    /// This is extracted from the `next` header in the HTTP response.
41    /// Use this with `execute_next_link()` to fetch the next batch of records.
42    pub next_link: Option<String>,
43
44    /// Number of records in this response
45    pub record_count: usize,
46}
47
48impl ReplicationResponse {
49    /// Create a new replication response
50    ///
51    /// This is typically called internally by the client. You usually don't
52    /// need to construct this yourself.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// # use reso_client::ReplicationResponse;
58    /// # use serde_json::json;
59    /// let records = vec![json!({"ListingKey": "12345"})];
60    /// let response = ReplicationResponse::new(records, None);
61    /// assert_eq!(response.record_count, 1);
62    /// assert!(!response.has_more());
63    /// ```
64    pub fn new(records: Vec<JsonValue>, next_link: Option<String>) -> Self {
65        let record_count = records.len();
66        Self {
67            records,
68            next_link,
69            record_count,
70        }
71    }
72
73    /// Check if there are more records available
74    ///
75    /// Returns `true` if there's a next link available for pagination.
76    ///
77    /// # Examples
78    ///
79    /// ```no_run
80    /// # use reso_client::{ResoClient, ReplicationQueryBuilder};
81    /// # async fn example(client: &ResoClient) -> Result<(), Box<dyn std::error::Error>> {
82    /// let query = ReplicationQueryBuilder::new("Property")
83    ///     .top(2000)
84    ///     .build()?;
85    ///
86    /// let response = client.execute_replication(&query).await?;
87    ///
88    /// if response.has_more() {
89    ///     println!("More records available!");
90    ///     let next_response = client.execute_next_link(
91    ///         response.next_link().unwrap()
92    ///     ).await?;
93    /// }
94    /// # Ok(())
95    /// # }
96    /// ```
97    pub fn has_more(&self) -> bool {
98        self.next_link.is_some()
99    }
100
101    /// Get the next link URL if available
102    ///
103    /// Returns `Some(&str)` with the URL for the next page, or `None` if
104    /// there are no more records.
105    ///
106    /// # Examples
107    ///
108    /// ```no_run
109    /// # use reso_client::{ResoClient, ReplicationQueryBuilder};
110    /// # async fn example(client: &ResoClient) -> Result<(), Box<dyn std::error::Error>> {
111    /// let query = ReplicationQueryBuilder::new("Property").build()?;
112    /// let mut response = client.execute_replication(&query).await?;
113    /// let mut all_records = response.records.clone();
114    ///
115    /// // Fetch all pages
116    /// while let Some(next_url) = response.next_link() {
117    ///     response = client.execute_next_link(next_url).await?;
118    ///     all_records.extend(response.records.clone());
119    /// }
120    ///
121    /// println!("Total records: {}", all_records.len());
122    /// # Ok(())
123    /// # }
124    /// ```
125    pub fn next_link(&self) -> Option<&str> {
126        self.next_link.as_deref()
127    }
128}