acta-maker-sdk 0.4.3

Rust SDK for Acta options market makers — WebSocket client, order signing, message types
Documentation
use std::sync::Arc;

use tokio::sync::{broadcast, mpsc};

use crate::ws::types::ServerMessage;

#[derive(Debug, Clone)]
pub struct ManagedInbound {
    pub connection_epoch: u64,
    pub sequence: u64,
    pub received_at: std::time::Instant,
    pub(super) message: Arc<ServerMessage>,
}

impl ManagedInbound {
    #[must_use]
    pub fn message(&self) -> &ServerMessage {
        &self.message
    }

    #[must_use]
    pub fn message_arc(&self) -> Arc<ServerMessage> {
        Arc::clone(&self.message)
    }
}

impl AsRef<ServerMessage> for ManagedInbound {
    fn as_ref(&self) -> &ServerMessage {
        &self.message
    }
}

#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ManagedReceiveError {
    #[error("managed ws message stream closed")]
    Closed,
    #[error("managed ws subscriber lost {skipped} messages")]
    Gap { skipped: u64 },
}

pub struct ManagedMessageReceiver {
    pub(super) inner: broadcast::Receiver<ManagedInbound>,
    /// Set under `GapPolicy::Reconnect`: a lag asks the session to reconnect.
    pub(super) gap_tx: Option<mpsc::UnboundedSender<()>>,
}

impl ManagedMessageReceiver {
    pub async fn recv(&mut self) -> Result<ManagedInbound, ManagedReceiveError> {
        match self.inner.recv().await {
            Ok(message) => Ok(message),
            Err(broadcast::error::RecvError::Closed) => Err(ManagedReceiveError::Closed),
            Err(broadcast::error::RecvError::Lagged(skipped)) => {
                if let Some(gap_tx) = &self.gap_tx {
                    let _ = gap_tx.send(());
                }
                Err(ManagedReceiveError::Gap { skipped })
            }
        }
    }
}