1pub use dbn_macros::{
5 dbn_record, CsvSerialize, DbnAttr, JsonSerialize, PyFieldDesc, RecordDebug, WritePyRepr,
6};
7
8#[doc(hidden)]
13#[macro_export]
14macro_rules! rtype_dispatch_base {
15 ($rec_ref:expr, $handler:ident) => {{
16 use $crate::enums::RType;
18 use $crate::record::*;
19 match $rec_ref.rtype() {
20 Ok(RType::Mbp0) => Ok($handler!(TradeMsg)),
21 Ok(RType::Mbp1) => Ok($handler!(Mbp1Msg)),
22 Ok(RType::Mbp10) => Ok($handler!(Mbp10Msg)),
23 #[allow(deprecated)]
24 Ok(RType::OhlcvDeprecated)
25 | Ok(RType::Ohlcv1S)
26 | Ok(RType::Ohlcv1M)
27 | Ok(RType::Ohlcv1H)
28 | Ok(RType::Ohlcv1D)
29 | Ok(RType::OhlcvEod) => Ok($handler!(OhlcvMsg)),
30 Ok(RType::Imbalance) => Ok($handler!(ImbalanceMsg)),
31 Ok(RType::Status) => Ok($handler!(StatusMsg)),
32 Ok(RType::InstrumentDef)
33 if $rec_ref.record_size() < std::mem::size_of::<$crate::v2::InstrumentDefMsg>() =>
34 {
35 Ok($handler!($crate::v1::InstrumentDefMsg))
36 }
37 Ok(RType::InstrumentDef)
38 if $rec_ref.record_size() < std::mem::size_of::<$crate::v3::InstrumentDefMsg>() =>
39 {
40 Ok($handler!($crate::v2::InstrumentDefMsg))
41 }
42 Ok(RType::InstrumentDef) => Ok($handler!($crate::v3::InstrumentDefMsg)),
43 Ok(RType::SymbolMapping)
44 if $rec_ref.record_size() < std::mem::size_of::<SymbolMappingMsg>() =>
45 {
46 Ok($handler!($crate::v1::SymbolMappingMsg))
47 }
48 Ok(RType::SymbolMapping) => Ok($handler!(SymbolMappingMsg)),
49 Ok(RType::Error) if $rec_ref.record_size() < std::mem::size_of::<ErrorMsg>() => {
50 Ok($handler!($crate::v1::ErrorMsg))
51 }
52 Ok(RType::Error) => Ok($handler!(ErrorMsg)),
53 Ok(RType::System) if $rec_ref.record_size() < std::mem::size_of::<SystemMsg>() => {
54 Ok($handler!($crate::v1::SystemMsg))
55 }
56 Ok(RType::System) => Ok($handler!(SystemMsg)),
57 Ok(RType::Statistics)
58 if $rec_ref.record_size() < std::mem::size_of::<$crate::v3::StatMsg>() =>
59 {
60 Ok($handler!($crate::v1::StatMsg))
61 }
62 Ok(RType::Statistics) => Ok($handler!($crate::v3::StatMsg)),
63 Ok(RType::Mbo) => Ok($handler!(MboMsg)),
64 Ok(RType::Cmbp1) | Ok(RType::Tcbbo) => Ok($handler!(Cmbp1Msg)),
65 Ok(RType::Bbo1S) | Ok(RType::Bbo1M) => Ok($handler!(BboMsg)),
66 Ok(RType::Cbbo1S) | Ok(RType::Cbbo1M) => Ok($handler!(CbboMsg)),
67 Err(e) => Err(e),
68 }
69 }};
70}
71
72#[macro_export]
81macro_rules! rtype_dispatch {
82 ($rec_ref:expr, $this:ident.$generic_method:ident($($arg:expr),*).await$(,)?) => {{
84 macro_rules! handler {
85 ($r:ty) => {{
86 $this.$generic_method($rec_ref.get::<$r>().unwrap() $(, $arg)*).await
87 }}
88 }
89 $crate::rtype_dispatch_base!($rec_ref, handler)
90 }};
91 ($rec_ref:expr, $this:ident.$generic_method:ident($($arg:expr),*)$(,)?) => {{
93 macro_rules! handler {
94 ($r:ty) => {{
95 $this.$generic_method($rec_ref.get::<$r>().unwrap() $(, $arg)*)
96 }}
97 }
98 $crate::rtype_dispatch_base!($rec_ref, handler)
99 }};
100 ($rec_ref:expr, $generic_fn:ident($($arg:expr),*).await$(,)?) => {{
102 macro_rules! handler {
103 ($r:ty) => {{
104 $generic_fn($rec_ref.get::<$r>().unwrap() $(, $arg)*).await
105 }}
106 }
107 $crate::rtype_dispatch_base!($rec_ref, handler)
108 }};
109 ($rec_ref:expr, $generic_fn:ident($($arg:expr),*)$(,)?) => {{
111 macro_rules! handler {
112 ($r:ty) => {{
113 $generic_fn($rec_ref.get::<$r>().unwrap() $(, $arg)*)
114 }}
115 }
116 $crate::rtype_dispatch_base!($rec_ref, handler)
117 }};
118 ($rec_ref:expr, ts_out: true, $this:ident.$generic_method:ident($($arg:expr),*).await$(,)?) => {{
120 macro_rules! handler {
121 ($r:ty) => {{
122 $this.$generic_method($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*).await
123 }}
124 }
125 $crate::rtype_dispatch_base!($rec_ref, handler)
126 }};
127 ($rec_ref:expr, ts_out: true, $this:ident.$generic_method:ident($($arg:expr),*)$(,)?) => {{
129 macro_rules! handler {
130 ($r:ty) => {{
131 $this.$generic_method($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap(), $(, $arg)*)
132 }}
133 }
134 $crate::rtype_dispatch_base!($rec_ref, handler)
135 }};
136 ($rec_ref:expr, ts_out: true, $generic_fn:ident($($arg:expr),*).await$(,)?) => {{
138 macro_rules! handler {
139 ($r:ty) => {{
140 $generic_fn($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*).await
141 }}
142 }
143 $crate::rtype_dispatch_base!($rec_ref, handler)
144 }};
145 ($rec_ref:expr, ts_out: true, $generic_fn:ident($($arg:expr),*)$(,)?) => {{
147 macro_rules! handler {
148 ($r:ty) => {{
149 $generic_fn($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*)
150 }}
151 }
152 $crate::rtype_dispatch_base!($rec_ref, handler)
153 }};
154 ($rec_ref:expr, ts_out: $ts_out:expr, $this:ident.$generic_method:ident($($arg:expr),*).await$(,)?) => {{
156 macro_rules! handler {
157 ($r:ty) => {{
158 if $ts_out {
159 $this.$generic_method($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*).await
160 } else {
161 $this.$generic_method($rec_ref.get::<$r>().unwrap() $(, $arg)*).await
162 }
163 }}
164 }
165 $crate::rtype_dispatch_base!($rec_ref, handler)
166 }};
167 ($rec_ref:expr, ts_out: $ts_out:expr, $this:ident.$generic_method:ident($($arg:expr),*)$(,)?) => {{
169 macro_rules! handler {
170 ($r:ty) => {{
171 if $ts_out {
172 $this.$generic_method($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*)
173 } else {
174 $this.$generic_method($rec_ref.get::<$r>().unwrap() $(, $arg)*)
175 }
176 }}
177 }
178 $crate::rtype_dispatch_base!($rec_ref, handler)
179 }};
180 ($rec_ref:expr, ts_out: $ts_out:expr, $generic_fn:ident($($arg:expr),*).await$(,)?) => {{
182 macro_rules! handler {
183 ($r:ty) => {{
184 if $ts_out {
185 $generic_fn($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*).await
186 } else {
187 $generic_fn($rec_ref.get::<$r>().unwrap() $(, $arg)*).await
188 }
189 }}
190 }
191 $crate::rtype_dispatch_base!($rec_ref, handler)
192 }};
193 ($rec_ref:expr, ts_out: $ts_out:expr, $generic_fn:ident($($arg:expr),*)$(,)?) => {{
195 macro_rules! handler {
196 ($r:ty) => {{
197 if $ts_out {
198 $generic_fn($rec_ref.get::<$crate::WithTsOut<$r>>().unwrap() $(, $arg)*)
199 } else {
200 $generic_fn($rec_ref.get::<$r>().unwrap() $(, $arg)*)
201 }
202 }}
203 }
204 $crate::rtype_dispatch_base!($rec_ref, handler)
205 }};
206}
207
208#[doc(hidden)]
209#[macro_export]
210macro_rules! schema_dispatch_base {
211 ($schema:expr, $handler:ident) => {{
212 use $crate::enums::Schema;
213 use $crate::record::*;
214 match $schema {
215 Schema::Mbo => $handler!(MboMsg),
216 Schema::Mbp1 | Schema::Tbbo => $handler!(Mbp1Msg),
217 Schema::Bbo1S | Schema::Bbo1M => $handler!(BboMsg),
218 Schema::Mbp10 => $handler!(Mbp10Msg),
219 Schema::Trades => $handler!(TradeMsg),
220 Schema::Ohlcv1D
221 | Schema::Ohlcv1H
222 | Schema::Ohlcv1M
223 | Schema::Ohlcv1S
224 | Schema::OhlcvEod => {
225 $handler!(OhlcvMsg)
226 }
227 Schema::Definition => $handler!(InstrumentDefMsg),
228 Schema::Statistics => $handler!(StatMsg),
229 Schema::Status => $handler!(StatusMsg),
230 Schema::Imbalance => $handler!(ImbalanceMsg),
231 Schema::Cmbp1 | Schema::Tcbbo => {
232 $handler!(Cmbp1Msg)
233 }
234 Schema::Cbbo1S | Schema::Cbbo1M => {
235 $handler!(CbboMsg)
236 }
237 }
238 }};
239}
240
241#[macro_export]
246macro_rules! schema_dispatch {
247 ($schema:expr, $this:ident.$generic_method:ident($($arg:expr),*).await$(,)?) => {{
249 macro_rules! handler {
250 ($r:ty) => {{
251 $this.$generic_method::<$r>($($arg),*).await
252 }}
253 }
254 $crate::schema_dispatch_base!($schema, handler)
255 }};
256 ($schema:expr, $this:ident.$generic_method:ident($($arg:expr),*)$(,)?) => {{
258 macro_rules! handler {
259 ($r:ty) => {{
260 $this.$generic_method::<$r>($($arg),*)
261 }}
262 }
263 $crate::schema_dispatch_base!($schema, handler)
264 }};
265 ($schema:expr, $generic_fn:ident($($arg:expr),*).await$(,)?) => {{
267 macro_rules! handler {
268 ($r:ty) => {{
269 $generic_fn::<$r>($($arg),*).await
270 }}
271 }
272 $crate::schema_dispatch_base!($schema, handler)
273 }};
274 ($schema:expr, $generic_fn:ident($($arg:expr),*)$(,)?) => {{
276 macro_rules! handler {
277 ($r:ty) => {{
278 $generic_fn::<$r>($($arg),*)
279 }}
280 }
281 $crate::schema_dispatch_base!($schema, handler)
282 }};
283 ($schema:expr, ts_out: $ts_out:expr, $this:ident.$generic_method:ident($($arg:expr),*).await$(,)?) => {{
285 macro_rules! handler {
286 ($r:ty) => {{
287 if $ts_out {
288 $this.$generic_method::<$crate::WithTsOut<$r>>($($arg),*).await
289 } else {
290 $this.$generic_method::<$r>($($arg),*).await
291 }
292 }}
293 }
294 $crate::schema_dispatch_base!($schema, handler)
295 }};
296 ($schema:expr, ts_out: $ts_out:expr, $this:ident.$generic_method:ident($($arg:expr),*)$(,)?) => {{
298 macro_rules! handler {
299 ($r:ty) => {{
300 if $ts_out {
301 $this.$generic_method::<$crate::WithTsOut<$r>>($($arg),*)
302 } else {
303 $this.$generic_method::<$r>($($arg),*)
304 }
305 }}
306 }
307 $crate::schema_dispatch_base!($schema, handler)
308 }};
309 ($schema:expr, ts_out: $ts_out:expr, $generic_fn:ident($($arg:expr),*).await$(,)?) => {{
311 macro_rules! handler {
312 ($r:ty) => {{
313 if $ts_out {
314 $generic_fn::<$crate::WithTsOut<$r>>($($arg),*).await
315 } else {
316 $generic_fn::<$r>($($arg),*).await
317 }
318 }}
319 }
320 $crate::schema_dispatch_base!($schema, handler)
321 }};
322 ($schema:expr, ts_out: $ts_out:expr, $generic_fn:ident($($arg:expr),*)$(,)?) => {{
324 macro_rules! handler {
325 ($r:ty) => {{
326 if $ts_out {
327 $generic_fn::<$crate::WithTsOut<$r>>($($arg),*)
328 } else {
329 $generic_fn::<$r>($($arg),*)
330 }
331 }}
332 }
333 $crate::schema_dispatch_base!($schema, handler)
334 }};
335}
336
337#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
349#[macro_export]
350macro_rules! rtype_ts_out_dispatch {
351 ($rec_ref:expr, $ts_out:expr, $generic_fn:expr $(,$arg:expr)*) => {{
352 macro_rules! maybe_ts_out {
353 ($r:ty) => {{
354 if $ts_out {
355 $generic_fn($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*)
356 } else {
357 $generic_fn(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
358 }
359 }};
360 }
361 $crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
362 }};
363}
364#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
374#[macro_export]
375macro_rules! rtype_ts_out_method_dispatch {
376 ($rec_ref:expr, $ts_out:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
377 macro_rules! maybe_ts_out {
378 ($r:ty) => {{
379 if $ts_out {
380 $this.$generic_method($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*)
381 } else {
382 $this.$generic_method(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
383 }
384 }};
385 }
386 $crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
387 }};
388}
389#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
395#[macro_export]
396macro_rules! rtype_ts_out_async_dispatch {
397 ($rec_ref:expr, $ts_out:expr, $generic_fn:expr $(,$arg:expr)*) => {{
398 macro_rules! maybe_ts_out {
399 ($r:ty) => {{
400 if $ts_out {
401 $generic_fn($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*).await
402 } else {
403 $generic_fn(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*).await
404 }
405 }};
406 }
407 $crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
408 }};
409}
410#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
416#[macro_export]
417macro_rules! rtype_ts_out_async_method_dispatch {
418 ($rec_ref:expr, $ts_out:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
419 macro_rules! maybe_ts_out {
420 ($r:ty) => {{
421 if $ts_out {
422 $this.$generic_method($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*).await
423 } else {
424 $this.$generic_method(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*).await
425 }
426 }};
427 }
428 $crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
429 }};
430}
431#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
436#[macro_export]
437macro_rules! rtype_method_dispatch {
438 ($rec_ref:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
439 macro_rules! handler {
440 ($r:ty) => {{
441 $this.$generic_method( unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
443 }}
444 }
445 $crate::rtype_dispatch_base!($rec_ref, handler)
446 }};
447}
448#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
454#[macro_export]
455macro_rules! rtype_async_dispatch {
456 ($rec_ref:expr, $generic_fn:expr $(,$arg:expr)*) => {{
457 macro_rules! handler {
458 ($r:ty) => {{
459 $generic_fn( unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*).await
461 }}
462 }
463 $crate::rtype_dispatch_base!($rec_ref, handler)
464 }};
465}
466#[deprecated(since = "0.32.0", note = "Use the updated rtype_dispatch macro")]
476#[macro_export]
477macro_rules! rtype_dispatch_with_ts_out {
478 ($rec_ref:expr, $generic_fn:expr $(,$arg:expr)*) => {{
479 macro_rules! handler {
480 ($r:ty) => {{
481 $generic_fn( $rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*)
482 }}
483 }
484 $crate::rtype_dispatch_base!($rec_ref, handler)
485 };
486}}
487
488#[deprecated(since = "0.32.0", note = "Use the updated schema_dispatch macro")]
490#[macro_export]
491macro_rules! schema_method_dispatch {
492 ($schema:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
493 macro_rules! handler {
494 ($r:ty) => {{
495 $this.$generic_method::<$r>($($arg),*)
496 }}
497 }
498 $crate::schema_dispatch_base!($schema, handler)
499 }};
500}
501#[deprecated(since = "0.32.0", note = "Use the updated schema_dispatch macro")]
504#[macro_export]
505macro_rules! schema_ts_out_method_dispatch {
506 ($schema:expr, $ts_out:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
507 macro_rules! handler {
508 ($r:ty) => {{
509 if $ts_out {
510 $this.$generic_method::<WithTsOut<$r>>($($arg),*)
511 } else {
512 $this.$generic_method::<$r>($($arg),*)
513 }
514 }}
515 }
516 $crate::schema_dispatch_base!($schema, handler)
517 }};
518}
519#[deprecated(since = "0.32.0", note = "Use the updated schema_dispatch macro")]
522#[macro_export]
523macro_rules! schema_async_method_dispatch {
524 ($schema:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
525 macro_rules! handler {
526 ($r:ty) => {{
527 $this.$generic_method::<$r>($($arg),*).await
528 }}
529 }
530 $crate::schema_dispatch_base!($schema, handler)
531 }};
532}
533
534#[cfg(test)]
535mod tests {
536 use crate::{record::HasRType, rtype};
537
538 struct Dummy {}
539
540 #[allow(dead_code)]
541 impl Dummy {
542 fn on_rtype<T: HasRType>(&self) -> bool {
543 T::has_rtype(0xFF)
544 }
545
546 #[allow(clippy::extra_unused_type_parameters)]
547 fn on_rtype_2<T: HasRType>(&self, x: u64, y: u64) -> u64 {
548 x + y
549 }
550
551 async fn do_something<T: HasRType>(&self, arg: u8) -> bool {
552 T::has_rtype(arg)
553 }
554 }
555
556 fn has_rtype<T: HasRType>(arg: u8) -> bool {
557 T::has_rtype(arg)
558 }
559
560 #[test]
561 fn test_two_args() {
562 assert!(schema_dispatch!(
563 Schema::Imbalance,
564 has_rtype(rtype::IMBALANCE)
565 ))
566 }
567
568 #[test]
569 fn test_method_two_args() {
570 let dummy = Dummy {};
571 let ret = schema_dispatch!(Schema::Definition, dummy.on_rtype_2(5, 6));
572 assert_eq!(ret, 11);
573 }
574
575 #[test]
576 fn test_method_no_args() {
577 let dummy = Dummy {};
578 let ret = schema_dispatch!(Schema::Definition, dummy.on_rtype());
579 assert!(!ret);
580 }
581
582 #[cfg(feature = "async")]
583 mod r#async {
584 use super::*;
585
586 #[tokio::test]
587 async fn test_self() {
588 let target = Dummy {};
589 let ret_true = schema_dispatch!(
590 Schema::Trades,
591 target.do_something(crate::enums::rtype::MBP_0).await,
592 );
593 let ret_false = schema_dispatch!(Schema::Trades, target.do_something(0xff).await);
594 assert!(ret_true);
595 assert!(!ret_false);
596 }
597 }
598}