1use std::sync::atomic::{AtomicU64, Ordering};
7
8use brokapi_core::{InstrumentId, SubscribeOpts, SubscriptionId};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum MdSubKind {
13 OrderBook,
15 MarketTrades,
17 Quotes,
19 Candles,
21}
22
23#[derive(Debug, Clone)]
25pub struct MdSubscription {
26 pub id: SubscriptionId,
28 pub instrument: InstrumentId,
30 pub kind: MdSubKind,
32 pub opts: SubscribeOpts,
34 pub topic: String,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum UdSubKind {
41 OrderState,
43 Portfolio,
45 Executions,
47}
48
49#[derive(Debug, Clone)]
51pub struct UdSubscription {
52 pub id: SubscriptionId,
54 pub kind: UdSubKind,
56 pub opts: SubscribeOpts,
58 pub topics: Vec<String>,
60}
61
62pub struct SubIdGen(AtomicU64);
64
65impl SubIdGen {
66 pub fn new(start: u64) -> Self {
68 Self(AtomicU64::new(start))
69 }
70
71 pub fn next(&self) -> SubscriptionId {
73 SubscriptionId::new(self.0.fetch_add(1, Ordering::Relaxed) + 1)
74 }
75}
76
77#[derive(Default)]
79pub struct ReqIdGen(AtomicU64);
80
81impl ReqIdGen {
82 pub fn next(&self) -> String {
84 format!("r{}", self.0.fetch_add(1, Ordering::Relaxed) + 1)
85 }
86}
87
88pub async fn wait_ack<C>(
92 core: &tokio::sync::Mutex<C>,
93 notify: std::sync::Arc<tokio::sync::Notify>,
94 limit: std::time::Duration,
95 state: impl Fn(&C) -> (crate::core::SubState, Option<String>),
96) -> Result<(), brokapi_core::Error> {
97 use crate::core::SubState;
98 use brokapi_runtime::AckState;
99 brokapi_runtime::wait_ack(core, notify, limit, |c: &C| match state(c) {
100 (SubState::Active, _) => AckState::Confirmed,
101 (SubState::Failed, reason) => AckState::Refused(reason.unwrap_or_default()),
102 (SubState::Pending, _) => AckState::Pending,
103 })
104 .await
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn ids_count_up_from_the_start() {
113 let g = SubIdGen::new(1000);
114 assert_eq!(g.next().value(), 1001);
115 assert_eq!(g.next().value(), 1002);
116 let r = ReqIdGen::default();
117 assert_eq!((r.next().as_str(), r.next().as_str()), ("r1", "r2"));
118 }
119}