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