RefCast

Build Status Latest Version Rust Documentation

Safely cast &T to &U where the struct U contains a single field of type T.

toml [dependencies] ref-cast = "0.2"

Basic example

```rust

[macro_use]

extern crate refcast; use refcast::RefCast;

[derive(RefCast)]

[repr(C)]

struct U(String);

fn main() { let s = String::new();

// Safely cast from `&String` to `&U`.
let u = U::ref_cast(&s);

} ```

Realistic example

Suppose we have a multidimensional array represented in a flat buffer in row-major order for performance reasons, but we want to expose an indexing operation that works in column-major order because it is more intuitive in the context of our application.

```rust const MAP_WIDTH: usize = 4;

struct Tile(u8);

struct TileMap { storage: Vec, }

// tilemap[x][y] should give us tilemap.storage[y * MAP_WIDTH + x]. ```

The signature of the [Index] trait in Rust is such that the output is forced to be borrowed from the type being indexed. So something like the following is not going to work.

```rust struct Column<'a> { tilemap: &'a TileMap, x: usize, }

// Does not work! The output of Index must be a reference that is // borrowed from self. Here the type Column is not a reference. impl Index for TileMap { fn index(&self, x: usize) -> Column { assert!(x < MAP_WIDTH); Column { tilemap: self, x } } }

impl<'a> Index for Column<'a> { fn index(&self, y: usize) -> &Tile { &self.tilemap.storage[y * MAP_WIDTH + self.x] } } ```

Here is a working approach using RefCast.

```rust

[derive(RefCast)]

[repr(C)]

struct Strided([Tile]);

// Implement tilemap[x][y] as tilemap[x..][y * MAP_WIDTH]. impl Index for TileMap { type Output = Strided; fn index(&self, x: usize) -> &Self::Output { assert!(x < MAPWIDTH); RefCast::refcast(&self.storage[x..]) } }

impl Index for Strided { type Output = Tile; fn index(&self, y: usize) -> &Self::Output { &self.0[y * MAP_WIDTH] } } ```

License

Licensed under either of

at your option.

Contribution

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