1use exc_service::{ExchangeError, Request, SendExcService};
2use exc_types::SubscribeTickers;
3use futures::{future::MapErr, TryFutureExt};
4use std::{
5 future::Future,
6 task::{Context, Poll},
7};
8use tower_make::MakeService;
9
10#[derive(Debug, Clone, Copy, Default)]
12pub enum FirstTrade {
13 #[default]
15 Wait,
16 Bid,
18 Ask,
20 BidAsk,
22}
23
24#[derive(Debug, Default)]
26pub struct MakeTickersOptions {
27 prefer_trade_bid_ask: bool,
28 first_trade: FirstTrade,
29 accept_bid_ask_ts: bool,
30}
31
32impl MakeTickersOptions {
33 pub fn prefer_trade_bid_ask(mut self, flag: bool) -> Self {
35 self.prefer_trade_bid_ask = flag;
36 self
37 }
38
39 pub fn first_trade(mut self, mode: FirstTrade) -> Self {
42 self.first_trade = mode;
43 self
44 }
45
46 pub fn is_prefer_trade_bid_ask(&self) -> bool {
48 self.prefer_trade_bid_ask
49 }
50
51 pub fn get_first_trade(&self) -> FirstTrade {
53 self.first_trade
54 }
55
56 pub fn accept_bid_ask_ts(mut self, flag: bool) -> Self {
59 self.accept_bid_ask_ts = flag;
60 self
61 }
62
63 pub fn is_accept_bid_ask_ts(&self) -> bool {
65 self.accept_bid_ask_ts
66 }
67}
68
69pub trait MakeTickers {
71 type Service: SendExcService<SubscribeTickers>;
73
74 type Future: Future<Output = Result<Self::Service, ExchangeError>>;
76
77 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ExchangeError>>;
79
80 fn make_tickers(&mut self, options: MakeTickersOptions) -> Self::Future;
82
83 fn as_make_tickers_service(&mut self) -> AsService<'_, Self>
85 where
86 Self: Sized,
87 {
88 AsService { make: self }
89 }
90}
91
92impl<M> MakeTickers for M
93where
94 M: MakeService<
95 MakeTickersOptions,
96 SubscribeTickers,
97 Response = <SubscribeTickers as Request>::Response,
98 Error = ExchangeError,
99 >,
100 M::Service: SendExcService<SubscribeTickers>,
101 M::MakeError: Into<ExchangeError>,
102{
103 type Service = M::Service;
104
105 type Future = MapErr<M::Future, fn(M::MakeError) -> ExchangeError>;
106
107 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ExchangeError>> {
108 self.poll_ready(cx).map_err(Into::into)
109 }
110
111 fn make_tickers(&mut self, options: MakeTickersOptions) -> Self::Future {
112 self.make_service(options).map_err(Into::into)
113 }
114}
115
116crate::create_as_service!(
117 MakeTickers,
118 MakeTickersOptions,
119 make_tickers,
120 "Service returns by [`MakeTickers::as_make_tickers_service`]."
121);