sui_gql_client/queries/
packages_from_original.rs1use 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}