af_iperps/graphql/
ch_positions.rs1use af_move_type::MoveInstance;
2use af_sui_types::{ObjectId, Version};
3use enum_as_inner::EnumAsInner;
4use futures::Stream;
5use sui_gql_client::queries::fragments::{MoveValueRaw, PageInfoForward};
6pub use sui_gql_client::queries::Error;
7use sui_gql_client::queries::GraphQlClientExt as _;
8use sui_gql_client::{schema, GraphQlClient, GraphQlResponseExt as _};
9
10type Position = MoveInstance<crate::position::Position>;
11
12pub(super) fn query<C: GraphQlClient>(
13 client: &C,
14 ch: ObjectId,
15 version: Option<Version>,
16) -> impl Stream<Item = Result<(u64, Position), Error<C::Error>>> + '_ {
17 async_stream::try_stream! {
18 let mut vars = Variables {
19 ch,
20 version,
21 first: Some(client.max_page_size().await?),
22 after: None,
23 };
24 let mut has_next_page = true;
25 while has_next_page {
26 let (page_info, positions) = request(client, vars.clone()).await?;
27
28 vars.after = page_info.end_cursor.clone();
29 has_next_page = page_info.has_next_page;
30
31 for value in positions {
32 yield value;
33 }
34 }
35 }
36}
37
38async fn request<C: GraphQlClient>(
39 client: &C,
40 vars: Variables,
41) -> Result<
42 (
43 PageInfoForward,
44 impl Iterator<Item = (u64, Position)> + 'static,
45 ),
46 Error<C::Error>,
47> {
48 let response = client
49 .query::<Query, _>(vars)
50 .await
51 .map_err(Error::Client)?;
52 let data = response.try_into_data()?;
53
54 let ChDfsConnection { nodes, page_info } = extract(data)?;
55 Ok((page_info, nodes.into_iter().filter_map(filter_df)))
56}
57
58fn extract(data: Option<Query>) -> Result<ChDfsConnection, &'static str> {
59 graphql_extract::extract!(data => {
60 clearing_house? {
61 dfs
62 }
63 });
64 Ok(dfs)
65}
66
67fn filter_df(df: ChDf) -> Option<(u64, Position)> {
68 let df_name: MoveInstance<crate::keys::Position> = df.df_name?.try_into().ok()?;
69 let df_value_raw = df.df_value?.into_move_value().ok();
70 let df_value: Position = df_value_raw?.try_into().ok()?;
71
72 Some((df_name.value.account_id, df_value))
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 ch: ObjectId::ZERO,
83 version: None,
84 first: Some(10),
85 after: None,
86 };
87 let operation = Query::build(vars);
88 insta::assert_snapshot!(operation.query, @r###"
89 query Query($ch: SuiAddress!, $version: UInt53, $first: Int, $after: String) {
90 clearing_house: object(address: $ch, version: $version) {
91 dfs: dynamicFields(first: $first, after: $after) {
92 nodes {
93 df_name: name {
94 type {
95 repr
96 }
97 bcs
98 }
99 df_value: value {
100 __typename
101 ... on MoveValue {
102 type {
103 repr
104 }
105 bcs
106 }
107 }
108 }
109 pageInfo {
110 hasNextPage
111 endCursor
112 }
113 }
114 }
115 }
116 "###);
117}
118
119#[derive(cynic::QueryVariables, Clone, Debug)]
120struct Variables {
121 ch: ObjectId,
122 version: Option<Version>,
123 first: Option<i32>,
124 after: Option<String>,
125}
126
127#[derive(cynic::QueryFragment, Debug)]
128#[cynic(variables = "Variables")]
129struct Query {
130 #[arguments(address: $ch, version: $version)]
131 #[cynic(alias, rename = "object")]
132 clearing_house: Option<ClearingHouseObject>,
133}
134
135#[derive(cynic::QueryFragment, Debug)]
136#[cynic(graphql_type = "Object", variables = "Variables")]
137struct ClearingHouseObject {
138 #[arguments(first: $first, after: $after)]
139 #[cynic(alias, rename = "dynamicFields")]
140 dfs: ChDfsConnection,
141}
142
143#[derive(cynic::QueryFragment, Debug)]
144#[cynic(graphql_type = "DynamicFieldConnection")]
145struct ChDfsConnection {
146 nodes: Vec<ChDf>,
147 page_info: PageInfoForward,
148}
149
150#[derive(cynic::QueryFragment, Debug)]
151#[cynic(graphql_type = "DynamicField")]
152struct ChDf {
153 #[cynic(alias, rename = "name")]
154 df_name: Option<MoveValueRaw>,
155 #[cynic(alias, rename = "value")]
156 df_value: Option<ChDfValue>,
157}
158
159#[derive(cynic::InlineFragments, Debug, EnumAsInner)]
160#[cynic(graphql_type = "DynamicFieldValue")]
161enum ChDfValue {
162 MoveValue(MoveValueRaw),
163 #[cynic(fallback)]
164 Unknown,
165}