1use serde::{Deserialize, Serialize};
34use std::ops::{Deref, DerefMut};
35use thiserror::Error;
36
37#[derive(Debug, Clone, PartialEq)]
39pub enum Order {
40 Asc,
42 Desc,
44}
45
46#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
51pub struct Edge<N> {
52 pub cursor: Value,
54 pub node: N,
56}
57
58#[derive(Default, Debug, PartialEq, Serialize, Deserialize)]
60pub struct PageInfo {
61 pub has_previous_page: bool,
63 pub has_next_page: bool,
65 pub start_cursor: Option<Value>,
67 pub end_cursor: Option<Value>,
69}
70
71#[derive(Default, Debug, PartialEq, Serialize, Deserialize)]
75pub struct ReadResult<N> {
76 pub edges: Vec<Edge<N>>,
78 pub page_info: PageInfo,
80}
81
82impl<N> ReadResult<N> {
83 pub fn map<B, F>(self, f: F) -> ReadResult<B>
84 where
85 Self: Sized,
86 F: Fn(N) -> B,
87 {
88 ReadResult {
89 page_info: self.page_info,
90 edges: self
91 .edges
92 .into_iter()
93 .map(|e| Edge {
94 cursor: e.cursor.to_owned(),
95 node: f(e.node),
96 })
97 .collect(),
98 }
99 }
100}
101
102#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Default)]
107pub struct Value(pub String);
108
109impl Deref for Value {
110 type Target = String;
111 fn deref(&self) -> &Self::Target {
112 &self.0
113 }
114}
115
116impl From<String> for Value {
117 fn from(value: String) -> Self {
118 Self(value)
119 }
120}
121
122impl AsRef<[u8]> for Value {
123 fn as_ref(&self) -> &[u8] {
124 self.0.as_bytes()
125 }
126}
127
128pub trait Encode {
130 fn encode(&self) -> Result<Vec<u8>, CursorError>;
131}
132
133pub trait Decode: Sized {
134 fn decode(bytes: &[u8]) -> Result<Self, CursorError>;
135}
136
137impl<T: bitcode::Encode> Encode for T {
139 fn encode(&self) -> Result<Vec<u8>, CursorError> {
140 Ok(bitcode::encode(self))
141 }
142}
143
144impl<T: bitcode::DecodeOwned> Decode for T {
145 fn decode(bytes: &[u8]) -> Result<Self, CursorError> {
146 bitcode::decode(bytes).map_err(|e| CursorError::Bitcode(e.to_string()))
147 }
148}
149
150pub trait Cursor {
155 type T: Encode + Decode;
157
158 fn serialize(&self) -> Self::T;
160 fn serialize_cursor(&self) -> Result<Value, CursorError> {
162 use base64::{alphabet, engine::general_purpose, engine::GeneralPurpose, Engine};
163
164 let bytes = self.serialize().encode()?;
165 let engine = GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::PAD);
166
167 Ok(Value(engine.encode(&bytes)))
168 }
169 fn deserialize_cursor(value: &Value) -> Result<Self::T, CursorError> {
171 use base64::{alphabet, engine::general_purpose, engine::GeneralPurpose, Engine};
172
173 let engine = GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::PAD);
174 let bytes = engine.decode(value)?;
175
176 Self::T::decode(&bytes)
177 }
178}
179
180#[derive(Debug, Error)]
181pub enum CursorError {
182 #[error("base64 decode: {0}")]
183 Base64Decode(#[from] base64::DecodeError),
184
185 #[error("bitcode: {0}")]
186 Bitcode(String),
187}
188
189#[derive(Default, Serialize, Deserialize, Clone)]
206pub struct Args {
207 pub first: Option<u16>,
209 pub after: Option<Value>,
211 pub last: Option<u16>,
213 pub before: Option<Value>,
215}
216
217impl Args {
218 pub fn forward(first: u16, after: Option<Value>) -> Self {
219 Self {
220 first: Some(first),
221 after,
222 last: None,
223 before: None,
224 }
225 }
226
227 pub fn backward(last: u16, before: Option<Value>) -> Self {
228 Self {
229 first: None,
230 after: None,
231 last: Some(last),
232 before,
233 }
234 }
235
236 pub fn is_backward(&self) -> bool {
237 (self.last.is_some() || self.before.is_some())
238 && self.first.is_none()
239 && self.after.is_none()
240 }
241
242 pub fn get_info(&self) -> (u16, Option<Value>) {
243 if self.is_backward() {
244 (self.last.unwrap_or(40), self.before.clone())
245 } else {
246 (self.first.unwrap_or(40), self.after.clone())
247 }
248 }
249
250 pub fn limit(self, v: u16) -> Self {
251 if self.is_backward() {
252 Args::backward(self.last.unwrap_or(v).min(v), self.before)
253 } else {
254 Args::forward(self.first.unwrap_or(v).min(v), self.after)
255 }
256 }
257}
258
259#[derive(Debug, Error)]
260pub enum ReadError {
261 #[error("{0}")]
262 Unknown(#[from] anyhow::Error),
263
264 #[error("cursor: {0}")]
265 Cursor(#[from] CursorError),
266}
267
268pub struct Reader<T> {
286 data: Vec<T>,
287 args: Args,
288 order: Order,
289}
290
291impl<T> Reader<T>
292where
293 T: Cursor + Clone,
294 T: Send + Unpin,
295 T: Bind<T = T>,
296{
297 pub fn new(data: Vec<T>) -> Self {
298 Self {
299 data,
300 args: Args::default(),
301 order: Order::Asc,
302 }
303 }
304
305 pub fn order(&mut self, order: Order) -> &mut Self {
306 self.order = order;
307
308 self
309 }
310
311 pub fn desc(&mut self) -> &mut Self {
312 self.order(Order::Desc)
313 }
314
315 pub fn args(&mut self, args: Args) -> &mut Self {
316 self.args = args;
317
318 self
319 }
320
321 pub fn backward(&mut self, last: u16, before: Option<Value>) -> &mut Self {
322 self.args(Args {
323 last: Some(last),
324 before,
325 ..Default::default()
326 })
327 }
328
329 pub fn forward(&mut self, first: u16, after: Option<Value>) -> &mut Self {
330 self.args(Args {
331 first: Some(first),
332 after,
333 ..Default::default()
334 })
335 }
336
337 pub fn execute(&self) -> Result<ReadResult<T>, ReadError> {
338 let is_order_desc = matches!(
339 (&self.order, self.args.is_backward()),
340 (Order::Asc, true) | (Order::Desc, false)
341 );
342
343 let mut data = self.data.clone().into_iter().collect::<Vec<_>>();
344 T::sort_by(&mut data, is_order_desc);
345 let (limit, cursor) = self.args.get_info();
346
347 if let Some(cursor) = cursor.as_ref() {
348 let cursor = T::deserialize_cursor(cursor)?;
349 T::retain(&mut data, cursor, is_order_desc);
350 }
351
352 let data_len = data.len();
353 data = data.into_iter().take((limit + 1).into()).collect();
354
355 let has_more = data_len > data.len();
356 if has_more {
357 data.pop();
358 }
359
360 let mut edges = data
361 .into_iter()
362 .map(|node| Edge {
363 cursor: node
364 .serialize_cursor()
365 .expect("Error while serialize_cursor in assert_read_result"),
366 node,
367 })
368 .collect::<Vec<_>>();
369
370 if self.args.is_backward() {
371 edges = edges.into_iter().rev().collect();
372 }
373
374 let page_info = if self.args.is_backward() {
375 PageInfo {
376 has_previous_page: has_more,
377 start_cursor: edges.first().map(|e| e.cursor.to_owned()),
378 ..Default::default()
379 }
380 } else {
381 PageInfo {
382 has_next_page: has_more,
383 end_cursor: edges.last().map(|e| e.cursor.to_owned()),
384 ..Default::default()
385 }
386 };
387
388 Ok(ReadResult { edges, page_info })
389 }
390}
391
392impl<T> Deref for Reader<T> {
393 type Target = Vec<T>;
394
395 fn deref(&self) -> &Self::Target {
396 &self.data
397 }
398}
399
400impl<T> DerefMut for Reader<T> {
401 fn deref_mut(&mut self) -> &mut Self::Target {
402 &mut self.data
403 }
404}
405
406pub trait Bind {
410 type T: Cursor + Clone;
412
413 fn sort_by(data: &mut Vec<Self::T>, is_order_desc: bool);
415 fn retain(
417 data: &mut Vec<Self::T>,
418 cursor: <<Self as Bind>::T as Cursor>::T,
419 is_order_desc: bool,
420 );
421}