resend_rs/
list_opts.rs

1use std::ops::Index;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy)]
6pub struct ListBefore {}
7
8#[derive(Debug, Clone, Copy)]
9pub struct ListAfter {}
10
11#[derive(Debug, Clone, Copy)]
12pub struct TimeNotSpecified {}
13
14/// Query parameters for retrieving a list of things.
15///
16/// Note that [`ListOptions::default()`] applies no filters.
17///
18/// See <https://resend.com/docs/pagination> for more information.
19///
20/// ## Example
21///
22/// ```
23/// # use resend_rs::list_opts::ListOptions;
24/// let list_opts = ListOptions::default()
25///   .with_limit(3)
26///   .list_before("71f170f3-826e-47e3-9128-a5958e3b375e");
27/// ```
28#[must_use]
29#[derive(Debug, Clone, Serialize)]
30pub struct ListOptions<List = TimeNotSpecified> {
31    #[serde(skip)]
32    list: std::marker::PhantomData<List>,
33
34    #[serde(skip_serializing_if = "Option::is_none")]
35    limit: Option<u8>,
36
37    #[serde(rename = "before")]
38    before_id: Option<String>,
39
40    #[serde(rename = "after")]
41    after_id: Option<String>,
42}
43
44impl Default for ListOptions {
45    /// Applies no filters (old default behavior).
46    fn default() -> Self {
47        Self {
48            list: std::marker::PhantomData::<TimeNotSpecified>,
49            limit: None,
50            before_id: None,
51            after_id: None,
52        }
53    }
54}
55
56impl<T> ListOptions<T> {
57    /// Number of things to retrieve. If no limit is provided then the default limit will be used
58    /// which varies from endpoint to endpoint, consult the specific method's documentation.
59    ///
60    /// - min: 1
61    /// - max: 100
62    #[inline]
63    pub const fn with_limit(mut self, limit: u8) -> Self {
64        self.limit = Some(limit);
65        self
66    }
67}
68
69impl ListOptions<TimeNotSpecified> {
70    /// The id before which we'll retrieve the items. This id will *not* be included in the list.
71    #[inline]
72    pub fn list_before(self, id: &str) -> ListOptions<ListBefore> {
73        ListOptions::<ListBefore> {
74            list: std::marker::PhantomData,
75            limit: self.limit,
76            before_id: Some(id.to_string()),
77            after_id: None,
78        }
79    }
80
81    /// The id after which we'll retrieve the items. This id will *not* be included in the list.
82    #[inline]
83    pub fn list_after(self, id: &str) -> ListOptions<ListAfter> {
84        ListOptions::<ListAfter> {
85            list: std::marker::PhantomData,
86            limit: self.limit,
87            before_id: None,
88            after_id: Some(id.to_string()),
89        }
90    }
91}
92
93/// Paginated response.
94///
95/// See <https://resend.com/docs/pagination> for more information.
96#[must_use]
97#[derive(Debug, Clone, Deserialize)]
98pub struct ListResponse<T> {
99    pub has_more: bool,
100    pub data: Vec<T>,
101}
102
103impl<T> Index<usize> for ListResponse<T> {
104    type Output = T;
105
106    fn index(&self, index: usize) -> &Self::Output {
107        #[allow(clippy::indexing_slicing)]
108        &self.data[index]
109    }
110}
111
112impl<T> ListResponse<T> {
113    /// Equivalent to `self.data.is_empty()`.
114    #[inline]
115    pub const fn is_empty(&self) -> bool {
116        self.data.is_empty()
117    }
118
119    /// Equivalent to `self.data.len()`.
120    #[inline]
121    pub const fn len(&self) -> usize {
122        self.data.len()
123    }
124}