speedy 0.8.7

A fast binary serialization framework
Documentation
# A fast binary serialization framework

[![Documentation](https://docs.rs/speedy/badge.svg)](https://docs.rs/speedy/*/speedy/)

The goal of this crate is to provide fast, simple and easy binary serialization.

## Benchmarks

See [rust_serialization_benchmark](https://github.com/djkoloski/rust_serialization_benchmark) for benchmarks.

## Example

```rust
use std::borrow::Cow;
use speedy::{Readable, Writable, Endianness};

#[derive(PartialEq, Debug, Readable, Writable)]
enum Enum {
    A,
    B,
    C,
}

#[derive(PartialEq, Debug, Readable, Writable)]
struct Struct< 'a > {
    number: u64,
    string: String,
    vector: Vec< u8 >,
    cow: Cow< 'a, [i64] >,
    float: f32,
    enumeration: Enum
}

fn main() {
    let original = Struct {
        number: 0x12345678ABCDEF00,
        string: "A totally pointless string".to_owned(),
        vector: vec![ 1, 2, 3 ],
        cow: Cow::Borrowed( &[ 4, 5, 6 ] ),
        float: 3.1415,
        enumeration: Enum::C
    };

    let bytes = original.write_to_vec().unwrap();
    let deserialized: Struct =
        Struct::read_from_buffer( &bytes ).unwrap();

    assert_eq!( original, deserialized );
}
```

## Supported types

Out-of-box the following types are supported:

|                    Type |                            Serialized as |
| ----------------------- | ---------------------------------------- |
|                    `u8` |                                    as-is |
|                   `u16` |                                    as-is |
|                   `u32` |                                    as-is |
|                   `u64` |                                    as-is |
|                 `usize` |                                    `u64` |
|                    `i8` |                                    as-is |
|                   `i16` |                                    as-is |
|                   `i32` |                                    as-is |
|                   `i64` |                                    as-is |
|                   `f32` |                                    as-is |
|                   `f64` |                                    as-is |
|                  `bool` |                  `u8`, either `0` or `1` |
|                  `char` |                                    `u32` |
|                `String` |             `{length: u32, bytes: [u8]}` |
|          `Cow<'a, str>` |             `{length: u32, bytes: [u8]}` |
|                `Vec<T>` |             `{length: u32, values: [T]}` |
|          `Cow<'a, [T]>` |             `{length: u32, values: [T]}` |
|         `HashMap<K, V>` |          `{length: u32, values: [K, V]}` |
|        `BTreeMap<K, V>` |          `{length: u32, values: [K, V]}` |
|            `HashSet<T>` |             `{length: u32, values: [T]}` |
|           `BTreeSet<T>` |             `{length: u32, values: [T]}` |
|              `Range<T>` |                                 `(T, T)` |
|     `RangeInclusive<T>` |                                 `(T, T)` |
|             `Option<T>` |                    `(1_u8, T)` or `0_u8` |
|          `Result<T, E>` |               `(1_u8, T)` or `(0_u8, E)` |
|                    `()` |                                  nothing |
|                   `(T)` |                                    as-is |
|                `(T, T)` |                                    as-is |
|            `(T, .., T)` |                                    as-is |
|                 `enum`s |                 `{tag: u32, variant: T}` |
|              `AtomicU8` |                                     `u8` |
|              `AtomicI8` |                                     `i8` |
|             `AtomicU16` |                                    `u16` |
|             `AtomicI16` |                                    `i16` |
|             `AtomicU32` |                                    `u32` |
|             `AtomicI32` |                                    `i32` |
|             `AtomicU64` |                                    `u64` |
|             `AtomicI64` |                                    `i64` |
|            `NonZeroU32` |                                    `u32` |
|    `std::net::Ipv4Addr` |                                    `u32` |
|    `std::net::Ipv6Addr` |                                   `u128` |
|      `std::net::IpAddr` |    `{is_ipv4: u8, value: {u32 or u128}}` |
|   `std::time::Duration` |         `{secs: u64, subsec_nanos: u32}` |
| `std::time::SystemTime` | `std::time::Duration` since `UNIX_EPOCH` |
|            `uuid::Uuid` |                               `[u8; 16]` |

These are stable and will not change in the future.

## Field attributes

### `#[speedy(length = $expr)]`

Can be used on most standard containers to specify the field's length.
Can refer to any of the previous fields.

For example:

```rust
use speedy::{Readable, Writable};

#[derive(Readable, Writable)]
struct Struct {
    byte_count: u8,
    #[speedy(length = byte_count / 4)]
    data: Vec< u32 >
}
```

Before serializing you need to make sure that whatever is set as `length`
is equal to the `.len()` of the field; if it's not then you will get
an error when trying to serialize it.

Setting this attribute changes the serialization format as follows:


|             Type |                Serialized as |
| ---------------- | ---------------------------- |
|         `Vec<T>` |                        `[T]` |
|   `Cow<'a, [T]>` |                        `[T]` |
|         `String` |                       `[u8]` |
|   `Cow<'a, str>` |                       `[u8]` |
|  `HashMap<K, V>` |                     `[K, V]` |
| `BTreeMap<K, V>` |                     `[K, V]` |
|     `HashSet<T>` |                        `[T]` |
|    `BTreeSet<T>` |                        `[T]` |

### `#[speedy(length_type = $ty)]`

Can be used to specify the exact size of the implicit length field of a container
as it is read or written.

Possible values:
  - `u7` (same as u8, but restricted to 7 bits for `u64_varint` compatibility)
  - `u8`
  - `u16`
  - `u32` (default)
  - `u64_varint`

### `#[speedy(varint)]`

Can be used only on `u64` fields. Forces the field to be serialized as a varint.

### `#[speedy(skip)]`

Skips a given field when reading and writing.

### `#[speedy(default_on_eof)]`

If an EOF is encountered when reading this field its value will be set
to the default value for its type and the EOF will be ignored.

### `#[speedy(constant_prefix = $expr)]`

Specifies a static string of bytes which will be written or has to be present
when reading before a given field.

## Enum attributes

### `#[speedy(tag_type = $ty)]`

Can be used to specify the exact size of the enum's tag as it is read or written.

Possible values:
  - `u7` (same as u8, but restricted to 7 bits for `u64_varint` compatibility)
  - `u8`
  - `u16`
  - `u32` (default)
  - `u64_varint`

### `#[speedy(peek_tag)]`

An enum marked with this attribute will not consume its tag value when reading
from a stream, nor will it write its own tag when writing.

## Enum variant attributes

### `#[speedy(tag = $expr)]`

Specifies a preset tag value to be used for a given enum variant.

## License

Licensed under either of

  * Apache License, Version 2.0, ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
  * MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.