dyn_struct 0.3.0

Construct dynamically sized types safely
Documentation
[![Crates.io](https://img.shields.io/crates/v/dyn_struct)](https://crates.io/crates/dyn_struct)
[![docs.rs](https://img.shields.io/docsrs/dyn_struct)](https://docs.rs/dyn_struct)

# `dyn_struct`

This crate allows you to safely initialize Dynamically Sized Types (DST) using
only safe Rust.

```rust
#[repr(C)]
#[derive(DynStruct)]
struct MyDynamicType {
    pub awesome: bool,
    pub number: u32,
    pub dynamic: [u32],
}

// the `new` function is generated by the `DynStruct` macro.
let foo: Box<MyDynamicType> = MyDynamicType::new(true, 123, [4, 5, 6, 7]);
assert_eq!(foo.awesome, true);
assert_eq!(foo.number, 123);
assert_eq!(&foo.dynamic, &[4, 5, 6, 7]);
```


## Why Dynamic Types?

In Rust, Dynamically Sized Types (DST) are everywhere. Slices (`[T]`) and trait
objects (`dyn Trait`) are the most common ones. However, it is also possible
to define your own! For example, this can be done by letting the last field in a
struct be a dynamically sized array (note the missing `&`):

```rust
struct MyDynamicType {
    awesome: bool,
    number: u32,
    dynamic: [u32],
}
```

This tells the Rust compiler that contents of the `dynamic`-array is laid out in
memory right after the other fields. This can be very preferable in some cases,
since remove one level of indirection and increase cache-locality.

However, there's a catch! Just as with slices, the compiler does not know how
many elements are in `dynamic`. Thus, we need what is called a fat-pointer which
stores both a pointer to the actual data, but also the length of the array
itself. As of releasing this crate, the only safe way to construct a dynamic
type is if we know the size of the array at compile-time. However, for most use
cases, that is not possible. Therefore this crate uses some `unsafe` behind the
scenes to work around the limitations of the language, all wrapped up in a safe
interface.


## The Derive Macro

The `DynStruct` macro can be applied to any `#[repr(C)]` struct that contains a
dynamically sized array as its last field. Fields only have a single constraint:
they have to implement `Copy`.

### Example

```rust
#[repr(C)]
#[derive(DynStruct)]
struct MyDynamicType {
    pub awesome: bool,
    pub number: u32,
    pub dynamic: [u32],
}
```

will produce a single `impl`-block with a `new` function. This function accepts all fileds in
the same order they were declared. The last field, however, can be anything implementing
`IntoIterator`:

```rust
impl MyDynamicType {
    pub fn new<I>(awesome: bool, number: u32, dynamic: I) -> Box<MyDynamicType> 
        where I: IntoIterator<Item = u32>,
              I::IntoIter: ExactSizeIterator,
    {
        // ... implementation details ...
    }
}
```

Due to the nature of dynamically sized types, the resulting value has to be
built on the heap. For safety reasons we currently only allow returning `Box`,
though in a future version we may also allow `Rc` and `Arc`. In the meantime it
is posible to use `Arc::from(MyDynamicType::new(...))`.