polyoxide-binance 0.48.0

Rust client library for Binance USDⓈ-M futures and spot market data and streams
Documentation
//! USDⓈ-M market streams on `fstream.binance.com`.
//!
//! Binance routes streams by path: `/public` carries partial depth and book
//! tickers, `/market` the rest of the streams here. Every [`StreamName`] knows
//! its path, the bare [`UsdmWs`] holds one connection on one path, and the
//! supervised tier ([`UsdmWsBuilder`]) keeps one connection per path, opened
//! when its first stream is wanted and closed when its last leaves.
//!
//! Binance acknowledges every `SUBSCRIBE` and enforces its connection rules by
//! closing the connection, so both tiers enforce them before sending: at most
//! [`MAX_STREAMS_PER_CONNECTION`] streams, [`MAX_NAMES_PER_REQUEST`] names per
//! request, and one request per [`MIN_REQUEST_INTERVAL`]. The measurements are
//! in `docs/specs/binance/OBSERVED.md`.
pub mod client;
pub mod error;
pub mod event;
#[cfg(any(test, feature = "test-server"))]
#[doc(hidden)]
pub mod fixtures;
mod protocol;
#[cfg(test)]
mod scripted;
pub mod stream;
pub mod supervised;

use std::{fmt, time::Duration};

pub use client::UsdmWs;
pub use error::{StopCause, UsdmWsError};
pub use event::{
    AggTradeEvent, BookTickerEvent, KlineBar, KlineEvent, MarkPriceEvent, PartialDepthEvent,
    Payload, SymbolType, TickerEvent, Update,
};
pub use stream::{DepthLevels, DepthSpeed, InvalidStreamName, StreamName};
pub use supervised::{DisconnectReason, Event, MembershipHandle, SupervisedUsdmWs, UsdmWsBuilder};

/// The production stream host.
pub const USDM_WS_BASE: &str = "wss://fstream.binance.com";

/// Streams one connection may carry. The 1025th is answered with an error,
/// and then the server closes the connection.
pub const MAX_STREAMS_PER_CONNECTION: usize = crate::shared::ws::MAX_STREAMS_PER_CONNECTION;

/// Stream names per `SUBSCRIBE` or `UNSUBSCRIBE`. 200 were measured accepted.
pub const MAX_NAMES_PER_REQUEST: usize = 200;

/// The shortest gap between two requests on one connection: 5 per second,
/// half the documented 10. Of 40 requests sent back to back, 15 were answered
/// before the server closed the connection.
pub const MIN_REQUEST_INTERVAL: Duration = Duration::from_millis(200);

/// Which routed path a connection is on.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum StreamPath {
    /// `/market`: tickers, mark prices, aggregate trades, klines.
    Market,
    /// `/public`: partial depth and book tickers.
    Public,
}

impl StreamPath {
    /// Both paths.
    pub const ALL: &'static [Self] = &[Self::Market, Self::Public];

    /// The path segment.
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Market => "market",
            Self::Public => "public",
        }
    }

    /// The combined-stream URL on `base`.
    pub(crate) fn url(self, base: &str) -> String {
        format!("{}/{}/stream", base.trim_end_matches('/'), self.as_str())
    }
}

impl fmt::Display for StreamPath {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}