Skip to main content

nado_sdk/utils/
response.rs

1use crate::engine::{CancelOrdersResponse, ExecuteResponseData};
2use eyre::{eyre, Result};
3use serde::de::DeserializeOwned;
4use serde::Deserialize;
5use serde_json::Value;
6
7use crate::utils::client_error::ClientError;
8
9#[derive(Deserialize, Debug)]
10#[serde(untagged)]
11pub enum NadoRestResponse<R> {
12    Success(R),
13    IPBlocked(CloudflareIPResponse),
14    IndexerError(IndexerError),
15    // This variant should be last, as it will match any response shape
16    Unknown(Value),
17}
18
19impl<R: DeserializeOwned + Send> NadoRestResponse<R> {
20    pub fn extract_response(self) -> Result<R> {
21        match self {
22            NadoRestResponse::Success(response) => Ok(response),
23            NadoRestResponse::IndexerError(error) => Err(eyre!(error.error)),
24            NadoRestResponse::IPBlocked(response) => {
25                Err(eyre!(ClientError::IPBlocked(format!("{response:?}"))))
26            }
27            NadoRestResponse::Unknown(value) => Ok(serde_json::from_value(value)?),
28        }
29    }
30}
31
32#[derive(Deserialize, Debug)]
33pub struct IndexerError {
34    pub error: String,
35    pub error_code: i32,
36}
37
38#[derive(Deserialize, Debug)]
39#[allow(dead_code)]
40pub struct CloudflareIPResponse {
41    reason: String,
42    blocked: bool,
43}
44
45#[doc(hidden)]
46#[macro_export]
47macro_rules! extract_response_data {
48    ($response:expr, $resp_type:ty => $data_type:ty) => {
49        if $response.status == Status::Failure {
50            Err(eyre!(serde_json::to_string_pretty(&$response)?))
51        } else {
52            Ok($response.data as Option<$data_type>)
53        }
54    };
55}
56
57// this function exists since the enums can be deserialized interchangeably since they are untagged
58// and have the same shape.
59pub fn match_cancel_orders_response(
60    execute_response_data: Option<ExecuteResponseData>,
61) -> Result<Option<CancelOrdersResponse>> {
62    match execute_response_data {
63        Some(data) => match data {
64            ExecuteResponseData::CancelOrders(response) => Ok(Some(response)),
65            ExecuteResponseData::CancelProductOrders(response) => Ok(Some(response)),
66            _ => Err(eyre!("Unexpected response type")),
67        },
68        None => Ok(None),
69    }
70}