sui_gql_client/queries/
objects_content.rs1use std::collections::HashMap;
2
3use af_sui_types::Address;
4use futures::TryStreamExt as _;
5use sui_gql_schema::schema;
6
7use super::fragments::{MoveValueRaw, ObjectFilterV2};
8use super::objects_flat::Variables;
9use super::outputs::RawMoveStruct;
10use super::{Error, objects_flat};
11use crate::{GraphQlClient, GraphQlResponseExt as _, missing_data};
12
13pub(super) async fn query<C: GraphQlClient>(
14 client: &C,
15 object_ids: Vec<Address>,
16) -> super::Result<HashMap<Address, RawMoveStruct>, C> {
17 let vars = Variables {
18 after: None,
19 first: None,
20 filter: Some(ObjectFilterV2 {
21 object_ids: Some(&object_ids),
22 ..Default::default()
23 }),
24 };
25
26 let mut stream = std::pin::pin!(super::stream::forward(client, vars, request));
27
28 let mut raw_objs = HashMap::new();
29
30 while let Some(object) = stream.try_next().await? {
31 let object_id = object.object_id;
32 let struct_ = object
33 .as_move_object
34 .ok_or(missing_data!("Not a Move object"))?
35 .contents
36 .ok_or(missing_data!("Object contents"))?
37 .try_into()
38 .expect("Only structs can be top-level objects");
39 raw_objs.insert(object_id, struct_);
40 }
41
42 Ok(raw_objs)
43}
44
45type Query = objects_flat::Query<Object>;
46
47async fn request<C: GraphQlClient>(
48 client: &C,
49 vars: Variables<'_>,
50) -> super::Result<
51 super::stream::Page<impl Iterator<Item = super::Result<Object, C>> + 'static + use<C>>,
52 C,
53> {
54 let data = client
55 .query::<Query, _>(vars)
56 .await
57 .map_err(Error::Client)?
58 .try_into_data()?;
59
60 graphql_extract::extract!(data => {
61 objects
62 });
63
64 Ok(super::stream::Page {
65 info: objects.page_info.into(),
66 data: objects.nodes.into_iter().map(Ok),
67 })
68}
69
70#[cfg(test)]
71#[allow(clippy::unwrap_used)]
72#[test]
73fn gql_output() {
74 use cynic::QueryBuilder as _;
75
76 let vars = Variables {
77 filter: None,
78 first: None,
79 after: None,
80 };
81 let operation = Query::build(vars);
82 insta::assert_snapshot!(operation.query, @r###"
83 query Query($filter: ObjectFilter, $after: String, $first: Int) {
84 objects(filter: $filter, first: $first, after: $after) {
85 nodes {
86 address
87 asMoveObject {
88 contents {
89 type {
90 repr
91 }
92 bcs
93 }
94 }
95 }
96 pageInfo {
97 hasNextPage
98 endCursor
99 }
100 }
101 }
102 "###);
103}
104
105#[derive(cynic::QueryFragment, Clone, Debug)]
106struct Object {
107 #[cynic(rename = "address")]
108 object_id: Address,
109 as_move_object: Option<super::fragments::MoveObjectContent<MoveValueRaw>>,
110}