simulator-api 0.8.0

Wire-protocol types for the Solana simulator backtest WebSocket API
Documentation
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

/// Response body of `GET /usage`.
#[derive(Debug, Serialize, Deserialize)]
pub struct UsageReport {
    pub api_key_name: String,
    pub since: DateTime<Utc>,
    pub until: DateTime<Utc>,
    pub sessions: SessionCounts,
    pub compute: ComputeTotals,
}

/// Raw `backtest_session_*` point counts for this api key in the window, by
/// outcome — not session-deduplicated, so the three need not balance (a
/// pre-start failure has no `started`; a cross-manager handoff re-emits
/// `started`). Billing uses the compute totals, which derive only from the
/// terminal completed/failed points.
#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
pub struct SessionCounts {
    pub started: u64,
    pub completed: u64,
    pub failed: u64,
}

/// Aggregated compute totals for a usage window.
#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
pub struct ComputeTotals {
    pub executed_slot_count: u64,
    pub session_duration_ms: u64,
}

impl SessionCounts {
    pub fn saturating_add(self, other: Self) -> Self {
        Self {
            started: self.started.saturating_add(other.started),
            completed: self.completed.saturating_add(other.completed),
            failed: self.failed.saturating_add(other.failed),
        }
    }
}

impl ComputeTotals {
    pub fn saturating_add(self, other: Self) -> Self {
        Self {
            executed_slot_count: self
                .executed_slot_count
                .saturating_add(other.executed_slot_count),
            session_duration_ms: self
                .session_duration_ms
                .saturating_add(other.session_duration_ms),
        }
    }
}