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#[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 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 #[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 #[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 #[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#[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 #[inline]
115 pub const fn is_empty(&self) -> bool {
116 self.data.is_empty()
117 }
118
119 #[inline]
121 pub const fn len(&self) -> usize {
122 self.data.len()
123 }
124}