dojo_orm/pagination/
async_graphql.rs

1use crate::pagination::{Cursor, Pagination};
2use crate::Model;
3use async_graphql::connection::{Connection, CursorType, Edge};
4use async_graphql::{
5    InputValueError, InputValueResult, OutputType, Scalar, ScalarType, SimpleObject, Value,
6};
7use std::fmt::Debug;
8
9#[Scalar]
10impl ScalarType for Cursor {
11    fn parse(value: Value) -> InputValueResult<Self> {
12        if let Value::String(value) = &value {
13            let cursor =
14                Cursor::decode(value).map_err(|e| InputValueError::custom(e.to_string()))?;
15            Ok(cursor)
16        } else {
17            Err(InputValueError::expected_type(value))
18        }
19    }
20
21    fn to_value(&self) -> Value {
22        let value = self.encode();
23        Value::String(value)
24    }
25}
26
27impl CursorType for Cursor {
28    type Error = anyhow::Error;
29
30    fn decode_cursor(s: &str) -> Result<Self, Self::Error> {
31        Self::decode(s)
32    }
33
34    fn encode_cursor(&self) -> String {
35        self.encode()
36    }
37}
38
39#[derive(SimpleObject, Debug, Clone)]
40pub struct AdditionalFields {
41    pub total_nodes: i64,
42}
43
44impl<T> From<Pagination<T>> for Connection<Cursor, T, AdditionalFields>
45where
46    T: OutputType + Model + Debug,
47{
48    fn from(value: Pagination<T>) -> Self {
49        let mut connection = Connection::with_additional_fields(
50            value.has_previous,
51            value.has_next,
52            AdditionalFields {
53                total_nodes: value.total_nodes,
54            },
55        );
56
57        connection.edges = value
58            .items
59            .into_iter()
60            .map(|item| Edge::new(item.cursor(), item))
61            .collect::<Vec<_>>();
62
63        connection
64    }
65}