protocol/
lib.rs

1//! Simple packet-based protocol definitions in Rust.
2//!
3//! * The [Parcel] trait defines any type that can be serialized
4//!   to a connection.
5//! * The [wire] module deals with transmission of [Parcel] objects.
6//!
7//! # Examples
8//!
9//! ## Get the raw bytes representing a parcel.
10//!
11//! ```
12//! extern crate protocol;
13//! #[macro_use] extern crate protocol_derive;
14//!
15//! #[derive(Protocol, Debug, PartialEq)]
16//! pub struct Health(pub u8);
17//!
18//! #[derive(Protocol, Debug, PartialEq)]
19//! pub struct Player {
20//!     pub name: String,
21//!     pub health: Health,
22//!     pub position: (i16, i16, i16),
23//!     pub velocity: (i16, i16, i16),
24//! }
25//!
26//! use protocol::Parcel;
27//!
28//! assert_eq!(vec![
29//!     0, 0, 0, 3, // "Bob" string length prefix
30//!     b'B', b'o', b'b', // The string "Bob".
31//!     100, // The health byte.
32//!     0, 10, 0, 81, 255, 151, // 2-byte x-position, y-position, and z-position.
33//!     0, 0, 0, 0, 0, 0, // 2-byte x-velocity, y-velocity, and z-velocity.
34//! ], Player {
35//!     name: "Bob".to_owned(),
36//!     health: Health(100),
37//!     position: (10, 81, -105),
38//!     velocity: (0, 0, 0),
39//! }.raw_bytes(&protocol::Settings::default()).unwrap());
40//! ```
41//!
42//! ## Enums
43//!
44//! Every enum has a value for each variant used to distinguish
45//! between each variant. This can be as simple as a 32-bit integer
46//! representing the variant's index. This is called the discriminator.
47//!
48//! ### String discriminators
49//!
50//! ```
51//! extern crate protocol;
52//! #[macro_use] extern crate protocol_derive;
53//!
54//! // This enum, like all enums, defaults to using String discriminators.
55//! #[derive(Protocol, Debug, PartialEq)]
56//! enum Foo { A, B, C }
57//!
58//! // This enum explicitly specifies a string discriminant.
59//! //
60//! // This is the default anyway and thus it is identical in layout
61//! // to the previous enum.
62//! #[derive(Protocol, Debug, PartialEq)]
63//! #[protocol(discriminant = "string")]
64//! enum Bar { A, B, C }
65//! ```
66//!
67//! By default, enums have `String` discriminators. This means that
68//! when serializing enum values to and from bytes, unless otherwise
69//! specified the variant's full name will be transmitted as a string.
70//!
71//! This allows variants to be added, modified, or reordered in
72//! a backwards-compatible way.
73//!
74//! ### Integer discriminators
75//!
76//! ```
77//! extern crate protocol;
78//! #[macro_use] extern crate protocol_derive;
79//!
80//! // An enum with integer discriminators.
81//! #[derive(Protocol, Debug, PartialEq)]
82//! #[protocol(discriminant = "integer")]
83//! enum Baz {
84//!     Fizz = 0, // override the default first discriminator of 1
85//!     Buzz, // defaults to `prior discriminator + 1`, therefore has a discriminator of 1.
86//!     Bing, // defaults to `prior discriminator + 1`, therefore has a discriminator of 2.
87//!     Boo = 1234,
88//!     Beez, // defaults to `prior discriminator + 1`, therefore has a discriminator of 1235.
89//! }
90//!
91//! use protocol::{Enum, Parcel};
92//!
93//! // By default, integer discriminators are 32-bits.
94//! assert_eq!([0u8, 0, 0, 2], &Baz::Bing.discriminator().raw_bytes(&protocol::Settings::default()).unwrap()[..]);
95//!
96//! assert_eq!(0, Baz::Fizz.discriminator());
97//! assert_eq!(1, Baz::Buzz.discriminator());
98//! assert_eq!(2, Baz::Bing.discriminator());
99//! assert_eq!(1234, Baz::Boo.discriminator());
100//! assert_eq!(1235, Baz::Beez.discriminator());
101//! ```
102//!
103//! It is possible to set the underlying integer type via the `#[repr(<type>)]` attribute.
104//!
105//! ```
106//! extern crate protocol;
107//! #[macro_use] extern crate protocol_derive;
108//!
109//! #[derive(Protocol, Debug, PartialEq)]
110//! #[protocol(discriminant = "integer")]
111//! #[repr(u8)] // Force discriminators to be 8-bit.
112//! pub enum Hello {
113//!     World(String), SolarSystem(String), LocalGroup(String),
114//!     Universe(String), Everything(String),
115//! }
116//!
117//! use protocol::{Enum, Parcel};
118//!
119//! assert_eq!([2, // 1-byte discriminator
120//!             0, 0, 0, 3, // string length
121//!             b'f', b'o', b'o', // the string
122//!             ], &Hello::SolarSystem("foo".to_owned()).raw_bytes(&protocol::Settings::default()).unwrap()[..]);
123//! ```
124//!
125//! Discriminators can be overriden on a per-variant basis via
126//! the `#[protocol(discriminator(<value>))]` attribute.
127//!
128//! In the case of trivial enums with no fields,
129//! the `Variant = <discriminator>` syntax may be used.
130//!
131//! ```
132//! extern crate protocol;
133//! #[macro_use] extern crate protocol_derive;
134//!
135//! #[derive(Protocol, Debug, PartialEq)]
136//! #[protocol(discriminant = "integer")]
137//! #[repr(u8)] // Force discriminators to be 8-bit.
138//! enum Numbered {
139//!     A = 1, B = 2, C = 111, D = 67,
140//! }
141//!
142//! #[derive(Protocol, Debug, PartialEq)]
143//! #[protocol(discriminant = "integer")]
144//! #[repr(u8)] // Force discriminators to be 8-bit.
145//! pub enum Hello {
146//!     World(String), SolarSystem(String), LocalGroup(String),
147//!     #[protocol(discriminator(100))]
148//!     Universe(String),
149//!     Everything(String),
150//! }
151//!
152//! use protocol::{Enum, Parcel};
153//!
154//! assert_eq!(111, Numbered::C.discriminator());
155//! assert_eq!(67, Numbered::D.discriminator());
156//!
157//! assert_eq!(1, Hello::World("foo".to_owned()).discriminator());
158//! assert_eq!(100, Hello::Universe("foo".to_owned()).discriminator());
159//! assert_eq!(101, Hello::Everything("foo".to_owned()).discriminator());
160//!
161//! ```
162
163pub use self::enum_ty::Enum;
164pub use self::parcel::Parcel;
165pub use self::errors::{Error, ErrorKind, Result, ResultExt, CharTryFromError, TryFromIntError};
166#[cfg(feature = "high-level-trait")] #[allow(deprecated)] pub use self::high_level::HighLevel;
167pub use self::settings::*;
168
169/// Custom derive  to implement `Parcel` for a type that contains other `Parcel`able types.
170///
171/// Example:
172///
173/// ```
174/// #[derive(protocol::Protocol)]
175/// struct Hello {
176///   foo: u8,
177///   bar: String,
178/// }
179/// ```
180#[cfg(feature = "derive")]
181pub use protocol_derive::Protocol;
182
183mod settings;
184#[macro_use]
185pub mod types;
186#[macro_use]
187pub mod wire;
188
189pub mod attributes;
190mod enum_ty;
191mod errors;
192#[cfg(feature = "high-level-trait")] mod high_level;
193pub mod hint;
194pub mod logic;
195mod parcel;
196pub mod util;
197
198
199extern crate byteorder;
200#[macro_use]
201extern crate error_chain;
202
203#[cfg(feature = "uuid")]
204extern crate uuid;
205extern crate num_traits;
206
207/// The default byte ordering.
208pub type DefaultByteOrder = ::byteorder::BigEndian;
209