tokio_ipc 0.1.0

Multi-protocol RPC framework built on top of tokio
Documentation
// tokio_socket/src/rpc/multi_protocol.rs - Support for handlers implementing multiple protocols

/// Macro to create a multi-protocol sender
/// This generates a sender type that implements all the necessary traits for multiple protocols
///
/// Usage:
/// ```ignore
/// multi_protocol_sender!(MySender impl [protocol1, protocol2]);
/// ```
#[macro_export]
macro_rules! protocol_sender {
    (
        $sender_name:ident impl [$($protocol:ident),* $(,)?]
    ) => {
        #[derive(Clone)]
        pub struct $sender_name {
            peer: $crate::RpcPeer,
        }

        impl $crate::RpcProtocolSender for $sender_name {
            fn peer(&self) -> &$crate::RpcPeer {
                &self.peer
            }
        }

        // Implement all protocol sender traits
        $(
            impl $protocol::Sender for $sender_name {}
        )*

        impl $crate::SendRpcProtocol for $sender_name {
            fn new(peer: $crate::RpcPeer) -> Self {
                Self { peer }
            }
        }
    };
}

/// Macro to create a multi-protocol receiver wrapper
/// This generates a type that impl ReceiveRpcProtocol and dispatches to the right protocol
///
/// Usage:
/// ```ignore
/// // Option 1: Generate a receiver type with automatic naming (appends "Receiver" to handler name)
/// protocol_handler!(MyHandler impl [protocol1, protocol2]);
/// // Creates: MyHandlerReceiver<MyHandler>
///
/// // Option 2: Specify custom receiver type name and handler type
/// protocol_handler!(MyReceiver impl [protocol1, protocol2] with MyHandler);
/// // Creates: MyReceiver (no generic parameter needed)
/// ```
#[macro_export]
macro_rules! protocol_handler {
    (
        $receiver_name:ident impl [$($protocol:ident),* $(,)?] with $handler_type:ty
    ) => {
        /// Auto-generated wrapper for multi-protocol handler
        #[derive(Clone)]
        pub struct $receiver_name {
            handler: $handler_type,
        }

        impl $receiver_name {
            pub fn new(handler: $handler_type) -> Self {
                Self { handler }
            }
        }

        impl $crate::ReceiveRpcProtocol for $receiver_name {
            async fn handle_packet(
                &self,
                protocol_id: u64,
                peer: &tokio_socket::SocketPeer,
                buf: Vec<u8>,
            ) -> anyhow::Result<Option<Vec<u8>>> {
                match protocol_id {
                    $(
                        $protocol::PROTOCOL_ID => {
                            let wrapper = $protocol::ReceiverWrapper::new(self.handler.clone());
                            use $crate::ProtocolHandler;
                            wrapper.handle_packet(peer, buf).await
                        }
                    )*
                    _ => Err(anyhow::anyhow!("Unknown protocol ID: 0x{:016x}", protocol_id))
                }
            }
        }
    };

    // Original syntax: auto-generate receiver name with generic parameter
    (
        $handler_name:ident impl [$($protocol:ident),* $(,)?]
    ) => {
        $crate::paste! {
            /// Auto-generated wrapper for multi-protocol handler
            #[derive(Clone)]
            pub struct [<$handler_name Receiver>]<H> {
                handler: H,
            }

            impl<H> [<$handler_name Receiver>]<H>
            where
                H: Clone + Send + Sync + 'static $( + $protocol::Receive)*
            {
                pub fn new(handler: H) -> Self {
                    Self { handler }
                }
            }

            impl<H> $crate::ReceiveRpcProtocol for [<$handler_name Receiver>]<H>
            where
                H: Clone + Send + Sync + 'static $( + $protocol::Receive)*
            {
                async fn handle_packet(
                    &self,
                    protocol_id: u64,
                    peer: &tokio_socket::SocketPeer,
                    buf: Vec<u8>,
                ) -> anyhow::Result<Option<Vec<u8>>> {
                    match protocol_id {
                        $(
                            $protocol::PROTOCOL_ID => {
                                let wrapper = $protocol::ReceiverWrapper::new(self.handler.clone());
                                use $crate::ProtocolHandler;
                                wrapper.handle_packet(peer, buf).await
                            }
                        )*
                        _ => Err(anyhow::anyhow!("Unknown protocol ID: 0x{:016x}", protocol_id))
                    }
                }
            }
        }
    };
}