paddle_rust_sdk/
paginated.rs

1//! # Helpers for working with paginated requests.
2
3use 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}