macro message_macro_derive

A macro to generate/parse binary representation of messages

3 releases

0.1.2 Jul 1, 2023
0.1.1 Jul 1, 2023
0.1.0 Jul 1, 2023

#696 in Procedural macros

MIT license

45KB
633 lines

Message Macro Derive

Message Macro Derive is a procedural macro crate that provides a custom derive macro for generating serialization and deserialization methods for network structs in Rust. The macro generates code to convert the struct into a byte representation (serialization) and vice versa (deserialization) using big endian order. It aims to simplify the process of working with network protocols and message formats by automating the conversion between Rust structs and byte arrays.

Note: Message Macro Derive is currently in development and has not been thoroughly tested in production environments. Use it with caution and ensure proper testing and validation in your specific use case.

Usage

To use Message Macro Derive, add it as a dependency in your Cargo.toml file:

[dependencies]
message_macro_derive = "0.1"

Then, import the BeBytes trait from the message_macro_derive crate and derive it for your struct:

use message_macro_derive::BeBytes;

#[derive(BeBytes)]
struct MyStruct {
    // Define your struct fields here...
}

The BeBytes derive macro will generate the following methods for your struct:

  • try_from_be_bytes(&[u8]) -> Result<(Self, usize), Box<dyn std::error::Error>>: A method to convert a byte slice into an instance of your struct. It returns a Result containing the deserialized struct and the number of consumed bytes.
  • to_be_bytes(&self) -> Vec<u8>: A method to convert the struct into a byte representation. It returns a Vec<u8> containing the serialized bytes.
  • field_size(&self) -> usize: A method to calculate the size (in bytes) of the struct.

Example

Here's an example showcasing the usage of the Message Macro Derive:

use message_macro_derive::BeBytes;

#[derive(BeBytes)]
struct MyStruct {
    #[U8(size(1), pos(0))]
    field1: u8,
    #[U8(size(4), pos(1))]
    field2: u8,
    field3: u32,
}

fn main() {
    let my_struct = MyStruct {
        field1: 1,
        field2: 7,
        field3: 42,
    };

    let bytes = my_struct.to_be_bytes();
    println!("Serialized bytes: {:?}", bytes);

    let deserialized = MyStruct::try_from_be_bytes(&bytes).unwrap().0;
    println!("Deserialized struct: {:?}", deserialized);
}

In this example, we define a struct MyStruct with three fields. The #[U8] attribute is used to specify the size and position of the fields for serialization. The BeBytes derive macro generates the serialization and deserialization methods for the struct, allowing us to easily convert it to bytes and back.

License

This project is licensed under the MIT License

Dependencies

~230–680KB
~16K SLoC