typed-index-collections

build status Latest Version docs.rs GitHub license Rust Version

The typed-index-collections crate provides typed index version of the Rust [slice] and [std::vec::Vec] types.

Introduction

When dealing with slices and vectors it is not safe to index all arrays with type-unsafe usizes as indices. Using slice and vector indexing might be useful in Data Oriented Design, when using Struct of Arrays, or when Rc and Weak usage is undesirable.

About

This crate provides typed index version of [slice] and [std::vec::Vec] types with custom index type. Containers only require the index to implement [Index] trait. If default feature impl-index-from is enabled, this trait is automatically implemented when [From<usize>] and [Into<usize>] are implemented. And their implementation can be easily done with [derive_more] crate and #[derive(From, Into)].

The [TiSlice] and [TiVec] structs are only wrappers around Rust [slice] and [std::vec::Vec] structs with custom index type and exposed raw property with original struct. They can be easily converted to matched Rust containers using [From] and [Into] traits. The structs mirrors the stable API of Rust [slice] and [std::vec::Vec] and forwards to it as much as possible.

Usage

First, add the following to your Cargo.toml:

toml [dependencies] typed-index-collections = "0.0.2"

This crate depends on the standard library by default that is useful for debugging and for some extra functionality. To use this crate in a #![no_std] context, use default-features = false in your Cargo.toml as shown below:

toml [dependencies.typed-index-collections] version = "0.0.2" default-features = false features = ["alloc", "impl-index-from"]

If you want to use [derive_more] for [From<usize>] and [Into<usize>] implementation add it to your Cargo.toml as shown below:

toml [dependencies] derive_more = "0.99" typed-index-collections = "0.0.2"

Examples

Simple example with [derive_more]: ```rust use typedindexcollections::TiVec; use derive_more::{From, Into};

[derive(From, Into)]

struct FooId(usize);

let mut foos: TiVec = std::vec![10, 11, 13].into(); foos.insert(FooId(2), 12); assert_eq!(foos[FooId(2)], 12); ```

Another example with [derive_more]: ```rust use typedindexcollections::{TiSlice, TiVec}; use derive_more::{From, Into};

[derive(Clone, Copy, Debug, From, Into, Eq, PartialEq)]

struct FooId(usize);

[derive(Clone, Copy, Debug, From, Into, Eq, PartialEq)]

struct BarId(usize);

[derive(Clone, Copy, Debug, Eq, PartialEq)]

struct Foo { value: usize, }

let first = Foo { value: 1 }; let second = Foo { value: 2 };

let sliceref = &[first, second][..]; let vec = std::vec![first, second]; let boxedslice = std::vec![first, second].intoboxedslice();

let typedindexsliceref: &TiSlice = sliceref.into(); let typedindexvec: TiVec = vec.into(); let typedindexboxedslice: std::boxed::Box> = boxedslice.into();

asserteq!(typedindexvec[FooId(1)], second); asserteq!(typedindexvec.raw[1], second); asserteq!(typedindexvec.last(), Some(&second)); asserteq!(typedindexvec.lastkeyvalue(), Some((FooId(1), &second))); asserteq!( typedindexvec.iterenumerated().next(), Some((FooId(0), &first)) ); // assert_eq!(vec[BarId(1)], second); // won't compile with incompable index

let sliceref: &[Foo] = typedindexsliceref.into(); let _vec: std::vec::Vec = typedindexvec.into(); let _boxedslice: std::boxed::Box<[Foo]> = typedindexboxed_slice.into(); ```

Documentation

[API Documentation]

Feature Flags

Similar crates

License

Licensed under either of

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.