iota_package_dump/
client.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use anyhow::{Context, Result, anyhow};
6use cynic::{Operation, QueryBuilder, http::ReqwestExt};
7use reqwest::IntoUrl;
8use serde::{Serialize, de::DeserializeOwned};
9
10pub(crate) struct Client {
11    inner: reqwest::Client,
12    url: reqwest::Url,
13}
14
15impl Client {
16    /// Create a new GraphQL client, talking to an IOTA GraphQL service at
17    /// `url`.
18    pub(crate) fn new(url: impl IntoUrl) -> Result<Self> {
19        Ok(Self {
20            inner: reqwest::Client::builder()
21                .user_agent(concat!("iota-package-dump/", env!("CARGO_PKG_VERSION")))
22                .build()
23                .context("Failed to create GraphQL client")?,
24            url: url.into_url().context("Invalid RPC URL")?,
25        })
26    }
27
28    pub(crate) async fn query<Q, V>(&self, query: Operation<Q, V>) -> Result<Q>
29    where
30        V: Serialize,
31        Q: DeserializeOwned + QueryBuilder<V> + 'static,
32    {
33        self.inner
34            .post(self.url.clone())
35            .run_graphql(query)
36            .await
37            .context("Failed to send GraphQL query")?
38            .data
39            .ok_or_else(|| anyhow!("Empty response to query"))
40    }
41}