pocketbase_rs/records/crud/
get_list.rs1use serde::{Deserialize, de::DeserializeOwned};
2
3use crate::PocketBase;
4use crate::error::RequestError;
5use crate::{Collection, RecordList};
6
7pub struct CollectionGetListBuilder<'a, T: Send + Deserialize<'a>> {
8 client: &'a PocketBase,
9 collection_name: &'a str,
10 page: Option<String>,
11 per_page: Option<String>,
12 sort: Option<&'a str>,
13 expand: Option<&'a str>,
14 filter: Option<&'a str>,
15 skip_total: bool,
16 _marker: std::marker::PhantomData<T>,
17}
18
19impl<'a> Collection<'a> {
20 #[must_use]
43 pub const fn get_list<T: Default + DeserializeOwned + Clone + Send>(
44 self,
45 ) -> CollectionGetListBuilder<'a, T> {
46 CollectionGetListBuilder {
47 client: self.client,
48 collection_name: self.name,
49 page: None,
50 per_page: None,
51 sort: None,
52 expand: None,
53 filter: None,
54 skip_total: false,
55 _marker: std::marker::PhantomData,
56 }
57 }
58}
59
60impl<'a, T: Default + DeserializeOwned + Clone + Send> CollectionGetListBuilder<'a, T> {
61 pub fn page(mut self, page: u16) -> Self {
63 self.page = Some(page.to_string());
64 self
65 }
66
67 pub fn per_page(mut self, per_page: u16) -> Self {
69 self.per_page = Some(per_page.to_string());
70 self
71 }
72
73 pub const fn sort(mut self, sort: &'a str) -> Self {
81 self.sort = Some(sort);
82 self
83 }
84
85 pub const fn filter(mut self, filter: &'a str) -> Self {
96 self.filter = Some(filter);
97 self
98 }
99
100 pub const fn expand(mut self, expand: &'a str) -> Self {
110 self.expand = Some(expand);
111 self
112 }
113
114 pub const fn skip_total(mut self, skip_total: bool) -> Self {
119 self.skip_total = skip_total;
120 self
121 }
122
123 pub async fn call(self) -> Result<RecordList<T>, RequestError> {
125 let url = format!(
126 "{}/api/collections/{}/records",
127 self.client.base_url, self.collection_name
128 );
129
130 let mut query_parameters: Vec<(&str, &str)> = vec![];
131
132 if let Some(page) = self.page.as_deref() {
133 query_parameters.push(("page", page));
134 }
135
136 if let Some(per_page) = self.per_page.as_deref() {
137 query_parameters.push(("perPage", per_page));
138 }
139
140 if let Some(sort) = self.sort {
141 query_parameters.push(("sort", sort));
142 }
143
144 if let Some(filter) = self.filter {
145 query_parameters.push(("filter", filter));
146 }
147
148 if let Some(expand) = self.expand {
149 query_parameters.push(("expand", expand));
150 }
151
152 let request = self
153 .client
154 .request_get(&url, Some(query_parameters))
155 .send()
156 .await;
157
158 let response = match request {
159 Ok(response) => response
160 .error_for_status()
161 .map_err(|err| match err.status() {
162 Some(reqwest::StatusCode::FORBIDDEN) => RequestError::Forbidden,
163 Some(reqwest::StatusCode::NOT_FOUND) => RequestError::NotFound,
164 Some(reqwest::StatusCode::TOO_MANY_REQUESTS) => RequestError::TooManyRequests,
165 _ => RequestError::Unhandled,
166 })?,
167 Err(error) => {
168 return Err(match error.status() {
169 Some(reqwest::StatusCode::FORBIDDEN) => RequestError::Forbidden,
170 Some(reqwest::StatusCode::NOT_FOUND) => RequestError::NotFound,
171 Some(reqwest::StatusCode::TOO_MANY_REQUESTS) => RequestError::TooManyRequests,
172 _ => RequestError::Unhandled,
173 });
174 }
175 };
176
177 let records = response
179 .json::<RecordList<T>>()
180 .await
181 .map_err(|error| RequestError::ParseError(error.to_string()))?;
182
183 Ok(records)
184 }
185}