Skip to main content

brokapi_tbank/core/
mod.rs

1//! Sans-io cores: protocol state machines without sockets, timers or async runtime.
2//!
3//! A core never touches the network. The connector owns the streams and feeds each message to the
4//! core as a frame, with the current time. The core answers with events (into an
5//! [`EventSink`](brokapi_sansio::EventSink)) and with requests to write to the stream. This makes the
6//! protocol logic testable without a server: frames in, events and requests out.
7//!
8//! - [`MdCore`] drives the one bidirectional market data stream.
9//! - [`UdCore`] keeps the order lifecycle, own trades and portfolio of one account.
10//!
11//! # Examples
12//!
13//! ```
14//! use std::time::{Duration, Instant};
15//! use brokapi_core::{InstrumentId, InstrumentKey, NativeId, SubscriptionId};
16//! use brokapi_sansio::{BrokerCore, DesiredSubscription, EventSink, SubscriptionKind, SubscriptionSet};
17//! use brokapi_tbank::core::{MdCore, MdFrame};
18//!
19//! let mut core = MdCore::new(Duration::from_secs(30));
20//! let mut events = EventSink::new();
21//!
22//! // The runtime tells the core that a stream is open. No socket is involved.
23//! core.on_frame(MdFrame::Connected, Instant::now(), &mut events);
24//!
25//! // The consumer wants an order book. The core queues the wire request.
26//! let sber = InstrumentId::new(InstrumentKey::new("SBER", "TQBR"), NativeId::Uid("uid-sber".into()));
27//! core.apply(&SubscriptionSet::with_subscriptions(vec![DesiredSubscription {
28//!     id: SubscriptionId::new(1),
29//!     kind: SubscriptionKind::OrderBook { instrument: sber, depth: 10 },
30//! }]));
31//!
32//! // First the ping settings, then the order book subscription.
33//! let mut requests = 0;
34//! while core.poll_request().is_some() {
35//!     requests += 1;
36//! }
37//! assert_eq!(requests, 2);
38//! assert_eq!(core.wire_count(), 1);
39//! ```
40
41pub mod md;
42pub mod ud;
43
44pub use md::{MdCore, MdFrame, SubUpdate};
45pub use ud::{UdCore, UdFrame};