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}