#[macro_export]
macro_rules! define_protocol {
(
$(#[$meta:meta])*
name: $name:ident,
transport: $transport:expr,
identify: |$data:ident| $body:expr
) => {
$(#[$meta])*
#[derive(Clone)]
pub struct $name;
impl $crate::core::types::RefractiumProtocol for $name {
#[inline]
fn identify(self: std::sync::Arc<Self>, $data: &[u8]) -> Option<$crate::core::types::ProtocolMatch> {
use $crate::heck::ToSnakeCase;
if $body {
return Some($crate::core::types::ProtocolMatch {
name: stringify!($name).to_snake_case(),
metadata: None,
implementation: self,
});
}
None
}
fn name(&self) -> String {
use $crate::heck::ToSnakeCase;
stringify!($name).to_snake_case()
}
fn transport(&self) -> $crate::core::types::Transport {
$transport
}
}
};
}
#[cfg(feature = "hooks")]
#[macro_export]
macro_rules! define_hook {
($name:ident, |$ctx:ident, $dir:ident, $pkt:ident| $body:expr) => {
#[derive(Clone)]
pub struct $name;
impl $crate::protocols::hooks::ProtocolHook for $name {
fn name(&self) -> &'static str {
stringify!($name)
}
fn on_packet(
&self,
$ctx: &$crate::protocols::hooks::HookContext,
$dir: $crate::protocols::hooks::Direction,
$pkt: $crate::bytes::Bytes,
) {
$body
}
}
};
}
#[cfg(feature = "hooks")]
#[macro_export]
macro_rules! hook_protocol {
(
wrapper: $wrapper:ident,
proto: $proto:ident,
hooks: [$($hook:expr),* $(,)?]
) => {
#[derive(Clone)]
pub struct $wrapper {
inner: $proto,
hooks: Vec<std::sync::Arc<dyn $crate::protocols::hooks::ProtocolHook>>,
}
impl $wrapper {
pub fn new() -> Self {
Self {
inner: $proto,
hooks: vec![$(std::sync::Arc::new($hook)),*],
}
}
pub fn with_hooks(hooks: Vec<std::sync::Arc<dyn $crate::protocols::hooks::ProtocolHook>>) -> Self {
Self {
inner: $proto,
hooks,
}
}
}
impl $crate::core::types::RefractiumProtocol for $wrapper {
#[inline]
fn identify(self: std::sync::Arc<Self>, data: &[u8]) -> Option<$crate::core::types::ProtocolMatch> {
let inner_proto = std::sync::Arc::new(self.inner.clone());
inner_proto.identify(data).map(|m| {
$crate::core::types::ProtocolMatch {
name: m.name,
metadata: m.metadata,
implementation: self,
}
})
}
fn name(&self) -> String {
use $crate::heck::ToSnakeCase;
stringify!($proto).to_snake_case()
}
fn transport(&self) -> $crate::core::types::Transport {
use $crate::core::types::RefractiumProtocol;
self.inner.transport()
}
fn hooks(&self) -> Vec<std::sync::Arc<dyn $crate::protocols::hooks::ProtocolHook>> {
self.hooks.clone()
}
}
impl Default for $wrapper {
fn default() -> Self {
Self::new()
}
}
};
}
macro_rules! refractium_trace {
($($arg:tt)*) => {
{
#[cfg(feature = "logging")]
tracing::trace!($($arg)*);
}
};
}
macro_rules! refractium_debug {
($($arg:tt)*) => {
{
#[cfg(feature = "logging")]
tracing::debug!($($arg)*);
}
};
}
macro_rules! refractium_info {
($($arg:tt)*) => {
{
#[cfg(feature = "logging")]
tracing::info!($($arg)*);
}
};
}
macro_rules! refractium_warn {
($($arg:tt)*) => {
{
#[cfg(feature = "logging")]
tracing::warn!($($arg)*);
}
};
}
macro_rules! refractium_error {
($($arg:tt)*) => {
{
#[cfg(feature = "logging")]
tracing::error!($($arg)*);
}
};
}
pub(crate) use refractium_debug;
pub(crate) use refractium_error;
pub(crate) use refractium_info;
pub(crate) use refractium_trace;
pub(crate) use refractium_warn;