sui_gql_client/queries/
packages_from_original.rs

1use af_sui_types::{Address, Version};
2
3use super::Error;
4use super::fragments::PageInfoForward;
5use crate::{GraphQlClient, Paged, PagedResponse, missing_data, schema};
6
7pub async fn query<C: GraphQlClient>(
8    client: &C,
9    package_id: Address,
10) -> Result<impl Iterator<Item = (Address, u64)> + use<C>, Error<C::Error>> {
11    let vars = Variables {
12        address: package_id,
13        first: None,
14        after: None,
15    };
16
17    let response: PagedResponse<Query> = client.query_paged(vars).await.map_err(Error::Client)?;
18    let (init, pages) = response
19        .try_into_data()?
20        .ok_or_else(|| missing_data!("No data"))?;
21
22    Ok(init
23        .package_versions
24        .nodes
25        .into_iter()
26        .chain(pages.into_iter().flat_map(|p| p.package_versions.nodes))
27        .map(|o| (o.address, o.version)))
28}
29
30#[derive(cynic::QueryVariables, Clone, Debug)]
31pub struct Variables {
32    address: Address,
33    after: Option<String>,
34    first: Option<i32>,
35}
36
37#[derive(cynic::QueryFragment, Debug)]
38#[cynic(variables = "Variables")]
39pub struct Query {
40    #[arguments(address: $address, first: $first, after: $after)]
41    pub package_versions: MovePackageConnection,
42}
43
44impl Paged for Query {
45    type Input = Variables;
46    type NextPage = Self;
47    type NextInput = Variables;
48
49    fn next_variables(&self, mut prev_vars: Self::Input) -> Option<Self::NextInput> {
50        let PageInfoForward {
51            has_next_page,
52            end_cursor,
53        } = &self.package_versions.page_info;
54        if *has_next_page {
55            prev_vars.after.clone_from(end_cursor);
56            Some(prev_vars)
57        } else {
58            None
59        }
60    }
61}
62
63#[derive(cynic::QueryFragment, Debug)]
64pub struct MovePackageConnection {
65    pub nodes: Vec<MovePackage>,
66    page_info: PageInfoForward,
67}
68
69#[derive(cynic::QueryFragment, Debug)]
70pub struct MovePackage {
71    pub address: Address,
72    pub version: Version,
73}
74
75#[cfg(test)]
76#[allow(clippy::unwrap_used)]
77#[test]
78fn gql_output() {
79    use cynic::QueryBuilder as _;
80
81    let vars = Variables {
82        address: Address::new(rand::random()).into(),
83        first: None,
84        after: None,
85    };
86    let operation = Query::build(vars);
87    insta::assert_snapshot!(operation.query, @r###"
88    query Query($address: SuiAddress!, $after: String, $first: Int) {
89      packageVersions(address: $address, first: $first, after: $after) {
90        nodes {
91          address
92          version
93        }
94        pageInfo {
95          hasNextPage
96          endCursor
97        }
98      }
99    }
100    "###);
101}