- Notifications
You must be signed in to change notification settings - Fork20
Easy protocol definitions in Rust
License
dylanmckay/protocol
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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 of
Parcel
s - 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.
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,}
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>,}
Any user-defined type can have theParcel
trait automatically derived.
#[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;}}}
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},}
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
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors5
Uh oh!
There was an error while loading.Please reload this page.