The typed-index-collections
crate provides [TiSlice
] and [TiVec
] structs
that are typed index versions of the Rust [slice
] and [std::vec::Vec
] types.
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.
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.
First, add the following to your Cargo.toml
:
toml
[dependencies]
typed-index-collections = "0.0.3"
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.3"
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.3"
Simple example with [derive_more
]:
```rust
use typedindexcollections::TiVec;
use derive_more::{From, Into};
struct FooId(usize);
let mut foos: TiVec
Another example with [derive_more
]:
```rust
use typedindexcollections::{TiSlice, TiVec};
use derive_more::{From, Into};
struct FooId(usize);
struct BarId(usize);
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
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
[API Documentation]
impl-index-from
(enabled by default) — Enables automatic [Index
]
trait implementation for types that implement [From<usize>
] and [Into<usize>
].alloc
(enabled by default) — Enables types and functions
which require memory allocation.std
(enabled by default) — Enables all [std
] features
such as memory allocations and [std::error::Error
] trait.serde
— Implements [Serialize
] and [Deserialize
] traits for slice type.serde-alloc
— Enable [alloc
] and serde/alloc
features.serde-std
— Enable [std
] and serde/std
features.typed_index_collection
] provides a Vec
wrapper with a very limited API.
Indices are u32 wrappers,
they are not customizable and can only index a specific type of container.indexed_vec
] is the closest copy of the IndexVec
struct from librustc_index
,
but API is also different from standard Rust [std::vec::Vec
]
and it has no typed index [slice
] alternative.index_vec
] have both [slice
] and [std::vec::Vec
] wrapper
and API closer to standard API.
But it implicitly allows you to use usize
for get methods and index expressions
that reduce type-safety,
and the macro define_index_type!
which is used to generate a newtyped index struct,
implicitly implements a lot of traits that would be better implemented
only when necessary using crates intended for this, such as [derive_more
].Licensed under either of
at your option.
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.