# durian_macros Macros for the `durian` crate These should not be used alone! The macros depend on Traits and paths defined in `durian` ## Procedural Macros Procedural macros for easily annotating structs as [`Packets`](https://docs.rs/durian/latest/durian/trait.Packet.html) and automatically implementing [`PacketBuilders`](https://docs.rs/durian/latest/durian/trait.PacketBuilder.html). The only requirement is the struct must be de/serializable, meaning all nested fields also need to be de/serializable. `#[bincode_packet]` will de/serialize your Packet using [`bincode`](https://docs.rs/bincode/latest/bincode/) and applies necessary derive macros automatically for you. ```rust use durian::bincode_packet; // Automatically implements Packet, and generates a PositionPacketBuilder that implements // PacketBuilder. You can also add other macros such as derive macros so long s they don't // conflict with what #[bincode_packet] adds (See bincode_packet documentation). #[bincode_packet] #[derive(Debug)] struct Position { x: i32, y: i32 } // Works for Unit (empty) structs as well #[bincode_packet] struct Ack; ``` You can also use the derive macros (`BinPacket` and `UnitPacket`) manually: ```rust use durian::serde::{Deserialize, Serialize}; use durian::{BinPacket, UnitPacket}; #[derive(Serialize, Deserialize, BinPacket)] #[serde(crate = "durian::serde")] struct Position { x: i32, y: i32 } #[derive(UnitPacket)] struct Ack; ``` ## Declarative Macros Regular macros for easy and concise calls to the [`PacketManager`](https://docs.rs/durian/latest/durian/struct.PacketManager.html). These include macros for registering all your `send` and `receive` packets: - [`register_send!(packet_manager, ...)`](`register_send`) - [`register_receive!(packet_manager, ...)`](`register_receive`) Where the `` a sequence of your `send` packet types, or a slice of those types, and `` are a sequence of tuples containing (your `receive` packet type, the associated packet builder), or a slice of those tuples. ### Example: ```rust use durian::{bincode_packet, register_send, register_receive, PacketManager}; // Send packets #[bincode_packet] struct Position { x: i32, y: i32 } #[bincode_packet] struct Ack; // Receive packets #[bincode_packet] struct UpdatePosition { x: i32, y: i32 } #[bincode_packet] struct NewMessage { message: String } fn main() { let manager = PacketManager::new(); let register_receive_results = register_receive!( manager, (UpdatePosition, UpdatePositionPacketBuilder), (NewMessage, NewMessagePacketBuilder) ); // Or equivalently in a slice, // register_receive_results!(manager, // [(UpdatePosition, UpdatePositionPacketBuilder), (NewMessage, NewMessagePacketBuilder)] // );` let register_send_results = register_send!(manager, Position, Ack); // Or equivalently in a slice, `register_send!(manager, [Position, Ack]);` // You can then validate that all the registrations were successful: assert!(register_receive_results.iter().all(|r| r.is_ok())); assert!(register_send_results.iter().all(|r| r.is_ok())); // The macros used above are equivalent to the following manual registration: // // manager.register_receive_packet::(UpdatePositionPacketBuilder); // manager.register_receive_packet::(NewMessagePacketBuilder); // manager.register_send_packet::(); // manager.register_send_packet::(); } ```