paddle_rust_sdk/
paginated.rs1use crate::{Error, Paddle, SuccessResponse};
4use reqwest::{Method, Url};
5use serde::{de::DeserializeOwned, Serialize};
6use serde_json::{Map, Value};
7use std::marker::PhantomData;
8
9pub struct Paginated<'a, T> {
10 client: &'a Paddle,
11 path: String,
12 query: Option<Value>,
13 _type: PhantomData<T>,
14 error: Option<Error>,
15}
16
17impl<'a, T> Paginated<'a, T> {
18 pub fn new<Q>(client: &'a Paddle, path: &str, query: Q) -> Self
19 where
20 Q: Serialize,
21 {
22 let (query, error) = match serde_json::to_value(query) {
23 Ok(query) => (Some(query), None),
24 Err(err) => (None, Some(Error::from(err))),
25 };
26 Self {
27 client,
28 path: path.to_string(),
29 query,
30 _type: PhantomData,
31 error,
32 }
33 }
34}
35
36impl<'a, T> Paginated<'a, T>
37where
38 T: DeserializeOwned,
39{
40 pub async fn next(&mut self) -> Result<Option<SuccessResponse<T>>, Error> {
41 if let Some(err) = self.error.take() {
42 return Err(err);
43 }
44 if let Some(query) = self.query.take() {
45 let response = self.client.send(query, Method::GET, &self.path).await?;
46 if let Some(pagination) = &response.meta.pagination {
47 if pagination.has_more {
48 let url = Url::parse(&pagination.next)?;
49 self.path = url.path().to_string();
50 let query: Map<String, Value> = url
51 .query()
52 .map(serde_qs::from_str)
53 .transpose()?
54 .unwrap_or_default();
55 self.query = Some(Value::Object(query));
56 }
57 }
58 Ok(Some(response))
59 } else {
60 Ok(None)
61 }
62 }
63}
64
65impl<'a, I> Paginated<'a, Vec<I>>
66where
67 I: DeserializeOwned,
68{
69 pub async fn all(&mut self) -> Result<Vec<I>, Error> {
70 let mut collected = Vec::new();
71 while let Some(response) = self.next().await? {
72 collected.extend(response.data.into_iter());
73 }
74 Ok(collected)
75 }
76}