Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Easy protocol definitions in Rust

License

NotificationsYou must be signed in to change notification settings

dylanmckay/protocol

Repository files navigation

Build StatusCrates.ioMIT licensed

Documentation

Easy protocol definitions in Rust.

This crate adds a custom derive that can be added to types, allowingstructured data to be sent and received from any IO stream.

Networking is built-in, with special support for TCP and UDP.

The protocol you define can be used outside of networking too - see theParcel::from_raw_bytes andParcel::raw_bytes methods.

This crate also provides:

  • TCP andUDP modules for easy sending and receiving ofParcels
  • A genericmiddleware library for automatic transformation of sent/received data
    • Middleware has already been written to supportcompression
    • Custom middleware can be implemented via a trait with two methods

Checkout theexamples folder for usage.

Usage

Add this to yourCargo.toml:

[dependencies]protocol = {version ="3.4",features = ["derive"] }

And then define a type with the#[derive(protocol::Protocol)] attribute:

#[derive(protocol::Protocol)]structHello{puba:String,pubb:u32,}

Under the hood

The most interesting part here is theprotocol::Parcel trait. Any type that implements this trait can then be serialized to and from a byte stream. All primitive types, standard collections, tuples, and arrays implement this trait.

This crate becomes particularly useful when you define your ownParcel types. You can use#[derive(protocol::Protocol)] to do this. Note that in order for a type to implementParcel, it must also implementClone,Debug, andPartialEq.

#[derive(Parcel,Clone,Debug,PartialEq)]pubstructHealth(f32);#[derive(Parcel,Clone,Debug,PartialEq)]pubstructSetPlayerPosition{pubposition:(f32,f32),pubhealth:Health,pubvalues:Vec<String>,}

Custom derive

Any user-defined type can have theParcel trait automatically derived.

Example

#[derive(protocol::Protocol,Clone,Debug,PartialEq)]pubstructHandshake;#[derive(protocol::Protocol,Clone,Debug,PartialEq)]pubstructHello{id:i64,data:Vec<u8>,}#[derive(protocol::Protocol,Clone,Debug,PartialEq)]pubstructGoodbye{id:i64,reason:String,}#[derive(protocol::Protocol,Clone,Debug,PartialEq)]pubstructNode{name:String,enabled:bool}#[protocol(discriminant ="integer")]#[derive(protocol::Protocol,Clone,Debug,PartialEq)]pubenumPacketKind{#[protocol(discriminator(0x00))]Handshake(Handshake),#[protocol(discriminator(0xaa))]Hello(Hello),#[protocol(discriminator(0xaf))]Goodbye(Goodbye),}fnmain(){use std::net::TcpStream;let stream =TcpStream::connect("127.0.0.1:34254").unwrap();letmut connection = protocol::wire::stream::Connection::new(stream, protocol::wire::middleware::pipeline::default());    connection.send_packet(&Packet::Handshake(Handshake)).unwrap();    connection.send_packet(&Packet::Hello(Hello{id:0,data:vec![55]})).unwrap();    connection.send_packet(&Packet::Goodbye(Goodbye{id:0,reason:"leaving".to_string()})).unwrap();loop{ifletSome(response) = connection.receive_packet().unwrap(){println!("{:?}", response);break;}}}

Enums

Discriminators

Enum values can be transmitted either by their 1-based variant index, or by transmitting the string name of each variant.

NOTE: The default behaviour is to usethe variant name as a string (string).

This behaviour can be changed by the#[protocol(discriminant = "<type>")] attribute.

Supported discriminant types:

  • string (default)
    • This transmits the enum variant name as the over-the-wire discriminant
    • This uses more bytes per message, but it very flexible
  • integer
    • This transmits the 1-based variant number as the over-the-wire discriminant
    • If enum variants have explicit discriminators, the
    • Enum variants cannot be reordered in the source without breaking the protocol
#[derive(protocol::Protocol,Clone,Debug,PartialEq)]#[protocol(discriminant ="string")]pubenumPlayerState{Stationary,Flying{velocity:(f32,f32,f32)},// Discriminators can be explicitly specified.#[protocol(discriminator("ArbitraryOverTheWireName"))]Jumping{height:f32},}

Misc

You can rename the variant for their serialisation.

#[derive(protocol::Protocol,Clone,Debug,PartialEq)]#[protocol(discriminant ="string")]pubenumFoo{Bar,#[protocol(name ="Biz")]// the Bing variant will be send/received as 'Biz'.Bing,Baz,}

About

Easy protocol definitions in Rust

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors5


[8]ページ先頭

©2009-2025 Movatter.jp