pub use dbn_macros::{dbn_record, CsvSerialize, DbnAttr, JsonSerialize, PyFieldDesc, RecordDebug};
#[doc(hidden)]
#[macro_export]
macro_rules! rtype_dispatch_base {
($rec_ref:expr, $handler:ident) => {{
use $crate::enums::RType;
use $crate::record::*;
match $rec_ref.rtype() {
Ok(rtype) => Ok(match rtype {
RType::Mbp0 => $handler!(TradeMsg),
RType::Mbp1 => $handler!(Mbp1Msg),
RType::Mbp10 => $handler!(Mbp10Msg),
#[allow(deprecated)]
RType::OhlcvDeprecated
| RType::Ohlcv1S
| RType::Ohlcv1M
| RType::Ohlcv1H
| RType::Ohlcv1D
| RType::OhlcvEod => $handler!(OhlcvMsg),
RType::Imbalance => $handler!(ImbalanceMsg),
RType::Status => $handler!(StatusMsg),
RType::InstrumentDef => {
if $rec_ref.record_size() < std::mem::size_of::<$crate::v2::InstrumentDefMsg>()
{
$handler!($crate::v1::InstrumentDefMsg)
} else if $rec_ref.record_size()
< std::mem::size_of::<$crate::v3::InstrumentDefMsg>()
{
$handler!($crate::v2::InstrumentDefMsg)
} else {
$handler!($crate::v3::InstrumentDefMsg)
}
}
RType::SymbolMapping => {
if $rec_ref.record_size() < std::mem::size_of::<SymbolMappingMsg>() {
$handler!($crate::v1::SymbolMappingMsg)
} else {
$handler!(SymbolMappingMsg)
}
}
RType::Error => {
if $rec_ref.record_size() < std::mem::size_of::<ErrorMsg>() {
$handler!($crate::v1::ErrorMsg)
} else {
$handler!(ErrorMsg)
}
}
RType::System => {
if $rec_ref.record_size() < std::mem::size_of::<SystemMsg>() {
$handler!($crate::v1::SystemMsg)
} else {
$handler!(SystemMsg)
}
}
RType::Statistics => $handler!(StatMsg),
RType::Mbo => $handler!(MboMsg),
RType::Cmbp1 | RType::Tcbbo => $handler!(Cmbp1Msg),
RType::Bbo1S | RType::Bbo1M => $handler!(BboMsg),
RType::Cbbo1S | RType::Cbbo1M => $handler!(CbboMsg),
}),
Err(e) => Err(e),
}
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! schema_dispatch_base {
($schema:expr, $handler:ident) => {{
use $crate::enums::Schema;
use $crate::record::*;
match $schema {
Schema::Mbo => $handler!(MboMsg),
Schema::Mbp1 | Schema::Tbbo => $handler!(Mbp1Msg),
Schema::Bbo1S | Schema::Bbo1M => $handler!(BboMsg),
Schema::Mbp10 => $handler!(Mbp10Msg),
Schema::Trades => $handler!(TradeMsg),
Schema::Ohlcv1D
| Schema::Ohlcv1H
| Schema::Ohlcv1M
| Schema::Ohlcv1S
| Schema::OhlcvEod => {
$handler!(OhlcvMsg)
}
Schema::Definition => $handler!(InstrumentDefMsg),
Schema::Statistics => $handler!(StatMsg),
Schema::Status => $handler!(StatusMsg),
Schema::Imbalance => $handler!(ImbalanceMsg),
Schema::Cmbp1 | Schema::Tcbbo => {
$handler!(Cmbp1Msg)
}
Schema::Cbbo1S | Schema::Cbbo1M => {
$handler!(CbboMsg)
}
}
}};
}
#[macro_export]
macro_rules! rtype_ts_out_dispatch {
($rec_ref:expr, $ts_out:expr, $generic_fn:expr $(,$arg:expr)*) => {{
macro_rules! maybe_ts_out {
($r:ty) => {{
if $ts_out {
$generic_fn($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*)
} else {
$generic_fn(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
}
}};
}
$crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
}};
}
#[macro_export]
macro_rules! rtype_ts_out_method_dispatch {
($rec_ref:expr, $ts_out:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
macro_rules! maybe_ts_out {
($r:ty) => {{
if $ts_out {
$this.$generic_method($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*)
} else {
$this.$generic_method(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
}
}};
}
$crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
}};
}
#[macro_export]
macro_rules! rtype_ts_out_async_dispatch {
($rec_ref:expr, $ts_out:expr, $generic_fn:expr $(,$arg:expr)*) => {{
macro_rules! maybe_ts_out {
($r:ty) => {{
if $ts_out {
$generic_fn($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*).await
} else {
$generic_fn(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*).await
}
}};
}
$crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
}};
}
#[macro_export]
macro_rules! rtype_ts_out_async_method_dispatch {
($rec_ref:expr, $ts_out:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
macro_rules! maybe_ts_out {
($r:ty) => {{
if $ts_out {
$this.$generic_method($rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*).await
} else {
$this.$generic_method(unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*).await
}
}};
}
$crate::rtype_dispatch_base!($rec_ref, maybe_ts_out)
}};
}
#[macro_export]
macro_rules! rtype_dispatch {
($rec_ref:expr, $generic_fn:expr $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$generic_fn( unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
}}
}
$crate::rtype_dispatch_base!($rec_ref, handler)
}};
}
#[macro_export]
macro_rules! rtype_method_dispatch {
($rec_ref:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$this.$generic_method( unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*)
}}
}
$crate::rtype_dispatch_base!($rec_ref, handler)
}};
}
#[macro_export]
macro_rules! rtype_async_dispatch {
($rec_ref:expr, $generic_fn:expr $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$generic_fn( unsafe { $rec_ref.get_unchecked::<$r>() } $(, $arg)*).await
}}
}
$crate::rtype_dispatch_base!($rec_ref, handler)
}};
}
#[macro_export]
macro_rules! rtype_dispatch_with_ts_out {
($rec_ref:expr, $generic_fn:expr $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$generic_fn( $rec_ref.get_unchecked::<WithTsOut<$r>>() $(, $arg)*)
}}
}
$crate::rtype_dispatch_base!($rec_ref, handler)
};
}}
#[macro_export]
macro_rules! schema_method_dispatch {
($schema:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$this.$generic_method::<$r>($($arg),*)
}}
}
$crate::schema_dispatch_base!($schema, handler)
}};
}
#[macro_export]
macro_rules! schema_ts_out_method_dispatch {
($schema:expr, $ts_out:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
if $ts_out {
$this.$generic_method::<WithTsOut<$r>>($($arg),*)
} else {
$this.$generic_method::<$r>($($arg),*)
}
}}
}
$crate::schema_dispatch_base!($schema, handler)
}};
}
#[macro_export]
macro_rules! schema_async_method_dispatch {
($schema:expr, $this:expr, $generic_method:ident $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$this.$generic_method::<$r>($($arg),*).await
}}
}
$crate::schema_dispatch_base!($schema, handler)
}};
}
#[macro_export]
macro_rules! schema_dispatch {
($schema:expr, $generic_fn:ident $(,$arg:expr)*) => {{
macro_rules! handler {
($r:ty) => {{
$generic_fn::<$r>($($arg),*)
}}
}
$crate::schema_dispatch_base!($schema, handler)
}};
}
#[cfg(test)]
mod tests {
use crate::{record::HasRType, schema_method_dispatch};
struct Dummy {}
#[allow(dead_code)]
impl Dummy {
fn on_rtype<T: HasRType>(&self) -> bool {
T::has_rtype(0xFF)
}
#[allow(clippy::extra_unused_type_parameters)]
fn on_rtype_2<T: HasRType>(&self, x: u64, y: u64) -> u64 {
x + y
}
async fn do_something<T: HasRType>(&self, arg: u8) -> bool {
T::has_rtype(arg)
}
}
#[test]
fn test_two_args() {
let ret = schema_method_dispatch!(Schema::Definition, Dummy {}, on_rtype_2, 5, 6);
assert_eq!(ret, 11);
}
#[test]
fn test_no_args() {
let ret = schema_method_dispatch!(Schema::Definition, Dummy {}, on_rtype);
assert!(!ret);
}
#[cfg(feature = "async")]
mod r#async {
use super::*;
use crate::schema_async_method_dispatch;
#[tokio::test]
async fn test_self() {
let target = Dummy {};
let ret_true = schema_async_method_dispatch!(
Schema::Trades,
target,
do_something,
crate::enums::rtype::MBP_0
);
let ret_false =
schema_async_method_dispatch!(Schema::Trades, target, do_something, 0xff);
assert!(ret_true);
assert!(!ret_false);
}
}
}