simulator-client 0.7.0

Async WebSocket client for the Solana simulator backtest API
Documentation
use std::time::Duration;

use simulator_api::{BacktestError, BacktestResponse};
use thiserror::Error;
use tokio_tungstenite::tungstenite;

pub type BacktestClientResult<T> = Result<T, BacktestClientError>;

#[derive(Debug, Error)]
pub enum BacktestClientError {
    #[error("invalid params: {message}")]
    InvalidParams { message: String },

    #[error("invalid API key header value: {0}")]
    InvalidApiKeyHeader(#[from] tungstenite::http::header::InvalidHeaderValue),

    #[error("failed to build websocket request for {url}: {source}")]
    BuildRequest {
        url: String,
        #[source]
        source: Box<tungstenite::Error>,
    },

    #[error("websocket connect to {url} failed: {source}")]
    Connect {
        url: String,
        #[source]
        source: Box<tungstenite::Error>,
    },

    #[error("timeout while {action} after {duration:?}")]
    Timeout {
        action: &'static str,
        duration: Duration,
    },

    #[error("failed to serialize request: {source}")]
    SerializeRequest {
        #[source]
        source: serde_json::Error,
    },

    #[error("failed to deserialize response: {source}; raw={raw}")]
    DeserializeResponse {
        raw: String,
        #[source]
        source: serde_json::Error,
    },

    #[error("remote error: {0}")]
    Remote(#[from] BacktestError),

    #[error("websocket closed: {reason}")]
    Closed { reason: String },

    #[error("unexpected response while {context}: {response:?}")]
    UnexpectedResponse {
        context: &'static str,
        response: Box<BacktestResponse>,
    },

    #[error("websocket error while {action}: {source}")]
    WebSocket {
        action: &'static str,
        #[source]
        source: Box<tungstenite::Error>,
    },

    #[error("HTTP request to {url} failed: {source}")]
    Http {
        url: String,
        #[source]
        source: Box<dyn std::error::Error + Send + Sync>,
    },
}