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