pub async fn query_with<Cursor, T, F, R, E>(
    after: Option<String>,
    before: Option<String>,
    first: Option<i32>,
    last: Option<i32>,
    f: F
) -> Result<T>where
    Cursor: CursorType + Send + Sync,
    <Cursor as CursorType>::Error: Display + Send + Sync + 'static,
    F: FnOnce(Option<Cursor>, Option<Cursor>, Option<usize>, Option<usize>) -> R,
    R: Future<Output = Result<T, E>>,
    E: Into<Error>,
Expand description

Parses the parameters and executes the query and return a custom Connection type.

Connection<T> and Edge<T> have certain limitations. For example, you cannot customize the name of the type, so you can use this function to execute the query and return a customized Connection type.

Examples

 
use async_graphql::*;
use async_graphql::types::connection::*;

#[derive(SimpleObject)]
struct MyEdge {
    cursor: usize,
    node: i32,
    diff: i32,
}

#[derive(SimpleObject)]
struct MyConnection {
    edges: Vec<MyEdge>,
    page_info: PageInfo,
}

struct Query;

#[Object]
impl Query {
    async fn numbers(&self,
        after: Option<String>,
        before: Option<String>,
        first: Option<i32>,
        last: Option<i32>
    ) -> Result<MyConnection> {
        query_with(after, before, first, last, |after, before, first, last| async move {
            let mut start = after.map(|after| after + 1).unwrap_or(0);
            let mut end = before.unwrap_or(10000);
            if let Some(first) = first {
                end = (start + first).min(end);
            }
            if let Some(last) = last {
                start = if last > end - start {
                    end
                } else {
                    end - last
                };
            }
            let connection = MyConnection {
                edges: (start..end).into_iter().map(|n| MyEdge {
                    cursor: n,
                    node: n as i32,
                    diff: (10000 - n) as i32,
                }).collect(),
                page_info: PageInfo {
                    has_previous_page: start > 0,
                    has_next_page: end < 10000,
                    start_cursor: Some(start.encode_cursor()),
                    end_cursor: Some(end.encode_cursor()),
                },
            };
            Ok::<_, Error>(connection)
        }).await
    }
}

let schema = Schema::new(Query, EmptyMutation, EmptySubscription);

assert_eq!(schema.execute("{ numbers(first: 2) { edges { node diff } } }").await.into_result().unwrap().data, value!({
    "numbers": {
        "edges": [
            {"node": 0, "diff": 10000},
            {"node": 1, "diff": 9999},
        ]
    },
}));

assert_eq!(schema.execute("{ numbers(last: 2) { edges { node diff } } }").await.into_result().unwrap().data, value!({
    "numbers": {
        "edges": [
            {"node": 9998, "diff": 2},
            {"node": 9999, "diff": 1},
        ]
    },
}));